package com.onlineMIS.ORM.DAO.headQ.barCodeGentor;

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.onlineMIS.ORM.DAO.Response;
import com.onlineMIS.ORM.DAO.chainS.chainMgmt.ChainProductShareGroupDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.SQLServer.ProductsMSDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.custMgmt.HeadQCustDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.inventory.HeadQSalesHisDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.inventory.InventoryOrderDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.inventory.InventoryOrderProductDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.inventoryFlow.HeadQInventoryStockDAOImpl;
import com.onlineMIS.ORM.DAO.headQ.supplier.purchase.PurchaseOrderProductDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.systemFile.SystemFileDaoImpl;
import com.onlineMIS.ORM.entity.base.Pager;
import com.onlineMIS.ORM.entity.chainS.user.ChainStore;
import com.onlineMIS.ORM.entity.headQ.SQLServer.PriceMS;
import com.onlineMIS.ORM.entity.headQ.SQLServer.ProductsMS;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Area;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.BarcodeCreationTemplate;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.BarcodeImportTemplate;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.BarcodeTemplate;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.BarcodeUpdateTemplate;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Brand;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.BrandVO;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Category;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Color;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.HeadQInputHelp;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.NumPerHand;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Product;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.ProductBarcode;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.ProductBarcodePic;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.ProductBarcodeVO;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.ProductIdentitySequence;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.ProductUnit;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Quarter;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Size;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.SystemFile;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.TagPrintTemplate;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.TagPrintVO;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.Year;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCust;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCustVO;
import com.onlineMIS.ORM.entity.headQ.inventoryFlow.HeadQInventoryStore;
import com.onlineMIS.ORM.entity.headQ.supplier.purchase.PurchaseOrder;
import com.onlineMIS.ORM.entity.headQ.supplier.purchase.PurchaseOrderProduct;
import com.onlineMIS.ORM.entity.headQ.user.UserInfor;
import com.onlineMIS.ORM.entity.headQ.inventory.HeadQSalesHistory;
import com.onlineMIS.ORM.entity.headQ.inventory.HeadQSalesHistoryId;
import com.onlineMIS.ORM.entity.headQ.inventory.InventoryOrder;
import com.onlineMIS.ORM.entity.headQ.inventory.InventoryOrderProduct;
import com.onlineMIS.ORM.entity.headQ.inventory.JinSuanOrderTemplate;
import com.onlineMIS.action.chainS.inventoryFlow.ImgDetailsVO;
import com.onlineMIS.action.headQ.barCodeGentor.BarcodeGenBasicData;
import com.onlineMIS.action.headQ.barCodeGentor.ProductActionFormBean;
import com.onlineMIS.action.headQ.barCodeGentor.ProductActionUIBean;
import com.onlineMIS.common.Common_util;
import com.onlineMIS.common.ExcelUtil;
import com.onlineMIS.common.FileUtils;
import com.onlineMIS.common.StrCheckUtils;
import com.onlineMIS.common.loggerLocal;
import com.onlineMIS.converter.JSONUtilDateConverter;
import com.onlineMIS.filter.SystemParm;
import com.onlineMIS.sorter.SortYear;
import com.opensymphony.xwork2.ActionContext;

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

@Service
public class ProductBarcodeService {

	@Autowired
	private ChainProductShareGroupDaoImpl chainProductShareGroupDaoImpl;
	@Autowired
	private ProductBarcodeDaoImpl productBarcodeDaoImpl;
	@Autowired
	private PurchaseOrderProductDaoImpl purchaseOrderProductDaoImpl;
	@Autowired
	private ProductDaoImpl productDaoImpl;
	@Autowired
	private InventoryOrderDAOImpl inventoryOrderDAOImpl;
	@Autowired
	private InventoryOrderProductDAOImpl inventoryOrderProductDAOImpl;
	@Autowired
	private HeadQSalesHisDAOImpl headQSalesHisDAOImpl;
	@Autowired
	private BrandDaoImpl brandDaoImpl;
	@Autowired
	private AreaDaoImpl areaDaoImpl;
	@Autowired
	private YearDaoImpl yearDaoImpl;
	@Autowired
	private QuarterDaoImpl quarterDaoImpl;
	@Autowired
	private CategoryDaoImpl categoryDaoImpl;
	@Autowired
	private ColorDaoImpl colorDaoImpl;
	@Autowired
	private SizeDaoImpl sizeDaoImpl;
	@Autowired
	private ProductUnitDaoImpl productUnitDaoImpl;
	@Autowired
	private NumPerHandDaoImpl numPerHandDaoImpl;
	@Autowired
	private HeadQInputHelpDaoImpl headQInputHelpDaoImpl;
	@Autowired
	private HeadQInventoryStockDAOImpl headQInventoryStockDAOImpl;

	@Autowired
	private ProductsMSDAOImpl productsMSImpl;
	@Autowired
	private ProductBarcodePicDaoImpl productBarcodePicDaoImpl;
	@Autowired
	private ProductIdentitySequenceDaoImpl productIsDaoImpl;
	@Autowired
	private SystemFileDaoImpl systemFileDaoImpl;
	@Autowired
	private HeadQCustDaoImpl headQCustDaoImpl;

	/**
	 * 只取出总部需要的数据
	 * 
	 * @return
	 */
	public BarcodeGenBasicData prepareBarcodeSourceDataForHead() {

		List<Area> areaList = areaDaoImpl.getAll(true);

		List<Year> yearList = yearDaoImpl.getAll(true);
		Collections.sort(yearList, new SortYear());

		
		List<Brand>brandList = brandDaoImpl.getAll(true);
		for(Brand brand: brandList) {
			brand.setBrand_Code(brand.getBrand_Name() + " " + brand.getComment());
		}
		
		List<Category> categoryLevelList = categoryDaoImpl.getHeadCategryByLevel(true, Category.LEVEL1,
				Category.STATUS_GOOD);

		List<Category> categoryList = categoryDaoImpl.getHeadCategryLevel2(true, Category.STATUS_GOOD);

		List<Quarter> quarterList = quarterDaoImpl.getAll(true);

		List<ProductUnit> unitList = productUnitDaoImpl.getAll(true);

		List<NumPerHand> numPerHandList = numPerHandDaoImpl.getAll(true);
		
		List<Color> colorList = colorDaoImpl.getAll(false);

		BarcodeGenBasicData basicData = new BarcodeGenBasicData();
		basicData.setBrandList(brandList);
		basicData.setAreaList(areaList);
		basicData.setYearList(yearList);
		basicData.setCategoryLevelList(categoryLevelList);
		basicData.setCategoryList(categoryList);
		basicData.setQuarterList(quarterList);
		basicData.setUnitList(unitList);
		basicData.setColorList(colorList);
		basicData.setNumPerHandList(numPerHandList);

		return basicData;
	}

	/**
	 * 取出所有表数据包括总部和连锁店
	 * 
	 * @return
	 */
	public BarcodeGenBasicData prepareBarcodeSourceData() {

		List<Area> areaList = areaDaoImpl.getAll(true);

		List<Year> yearList = yearDaoImpl.getAll(true);
		Collections.sort(yearList, new SortYear());

		List<Category> categoryLevelList = categoryDaoImpl.getHeadCategryByLevel(true, Category.LEVEL1,Category.STATUS_GOOD);

		List<Category> categoryList = categoryDaoImpl.getHeadCategryLevel2(true, Category.STATUS_GOOD);

		List<Quarter> quarterList = quarterDaoImpl.getAll(true);

		List<Color> colorList = colorDaoImpl.getAll(false);

		List<Size> sizeList = sizeDaoImpl.getAll(true);

		List<ProductUnit> unitList = productUnitDaoImpl.getAll(true);

		List<NumPerHand> numPerHandList = numPerHandDaoImpl.getAll(true);		

		BarcodeGenBasicData basicData = new BarcodeGenBasicData();
		basicData.setAreaList(areaList);
		basicData.setYearList(yearList);
		basicData.setCategoryLevelList(categoryLevelList);
		basicData.setCategoryList(categoryList);
		basicData.setQuarterList(quarterList);
		basicData.setUnitList(unitList);
		basicData.setNumPerHandList(numPerHandList);
		basicData.setColorList(colorList);
		basicData.setSizeList(sizeList);

		return basicData;
	}

	class SortBrand implements java.util.Comparator<Brand> {
		@Override
		public int compare(Brand arg0, Brand arg1) {
			int brand1 = 0;
			int brand2 = 0;

			brand1 = arg0.getBrand_ID();
			brand2 = arg1.getBrand_ID();

			return brand1 - brand2;
		}
	}

	/**
	 * getProductsForSimiliarProductCode 功能的扩展
	 * 
	 * @param productCode
	 * @param i
	 * @param pager
	 * @return
	 * @throws Exception
	 */
	public List<ProductBarcodeVO> getProductsForSimiliarProductCodeHeadq(String productCode, String factoryCode,int scope, int storeId,
			Pager pager) throws Exception {
		List<ProductBarcode> products = getProductsForSimiliarProductCode(productCode,factoryCode, scope, storeId, pager);

		List<ProductBarcodeVO> productBarcodeVOs = new ArrayList<ProductBarcodeVO>();

		for (ProductBarcode pBarcode : products) {

			ProductBarcodeVO vo = new ProductBarcodeVO(pBarcode);
			int inventoryLevel = headQInventoryStockDAOImpl.getProductStock(pBarcode.getId(), storeId, true);

			vo.setInventoryLevel(inventoryLevel);

			productBarcodeVOs.add(vo);
		}

		return productBarcodeVOs;
	}
	


	/**
	 * get the products by the similiar product code scope : -1 所有条码 （总部和连锁店做的条码） >0
	 * 总部条码 + 当前连锁店和关联连锁店条码 0 只有总部条码
	 * 
	 * @param productCode
	 * @return
	 */
	@Transactional
	public List<ProductBarcode> getProductsForSimiliarProductCode(String similiarProductCode,String factoryCode, int scope, int storeId,
			Pager pager) {
		boolean cache = false;

		// 1. check the pager
		if (pager.getTotalResult() == 0) {
			DetachedCriteria criteria = buildSearchProductCodeCriteria(similiarProductCode,factoryCode, scope);
			criteria.setProjection(Projections.rowCount());
			int totalRecord = Common_util
					.getProjectionSingleValue(productBarcodeDaoImpl.getByCriteriaProjection(criteria, false));
			pager.initialize(totalRecord);
		} else {
			pager.calFirstResult();
			cache = true;
		}

		DetachedCriteria criteria2 = buildSearchProductCodeCriteria(similiarProductCode, factoryCode,scope);

		return productBarcodeDaoImpl.getByCritera(criteria2, pager.getFirstResult(), pager.getRecordPerPage(), cache);
	}



	private DetachedCriteria buildSearchProductCodeCriteria(String productCode,String factoryCode, int scope) {
		DetachedCriteria criteria = DetachedCriteria.forClass(ProductBarcode.class);
		DetachedCriteria productCriteria = criteria.createCriteria("product");

		if (scope == 0)
			criteria.add(Restrictions.isNull("chainStore"));
		else if (scope > 0) {

			List<ChainStore> chainStores = chainProductShareGroupDaoImpl.getChainGroupStoreList(scope, null,
					Common_util.CHAIN_ACCESS_LEVEL_3);
			Set<Integer> chainIds = new HashSet<Integer>();
			for (ChainStore chain : chainStores) {
				chainIds.add(chain.getChain_id());
			}

			criteria.add(Restrictions.or(Restrictions.isNull("chainStore"),
					Restrictions.in("chainStore.chain_id", chainIds)));
		}

		if (StringUtils.isNotBlank(productCode)) {
			productCriteria.add(Restrictions.like("productCode", productCode, MatchMode.ANYWHERE));
		}
		if (StringUtils.isNotBlank(factoryCode)) {
			productCriteria.add(Restrictions.like("factoryCode", factoryCode, MatchMode.ANYWHERE));
		}
		Set<Integer> statusSet = new HashSet<Integer>();
		statusSet.add(ProductBarcode.STATUS_OK);
		statusSet.add(ProductBarcode.STATUS_NOT_PRODUCE);

		criteria.add(Restrictions.in("status", statusSet));

		productCriteria.addOrder(Order.desc("year.year_ID"));
		productCriteria.addOrder(Order.desc("quarter.quarter_ID"));
		productCriteria.addOrder(Order.desc("brand.brand_ID"));
		productCriteria.addOrder(Order.desc("productCode"));

		return criteria;
	}

	/**
	 * 1. 总部不能使用连锁店品牌 2. 总部不能使用连锁店种类 2.检查serial number如果填写
	 */
	@Transactional
	public Response checkErrorBeforeGenerateBarcode(Product product) {
		Response response = new Response();

		String serialNum = product.getSerialNum();
		String productCode = product.getProductCode();

//@todo: 以后扩展用
//		ProductsMS productsMS = productsMSDAOImpl.getBySerialNum(serialNum);
//		if (productsMS == null){
//			response.setReturnCode(Response.FAIL);
//			response.setMessage("无法在精算中找到对应编码的商品资料");
//			return response;
//		} else {
//			Product product2 = productDaoImpl.getBySerialNum(serialNum);
//			if (product2 != null){
//				response.setReturnCode(Response.FAIL);
//				response.setMessage("此编码已经存在于,条码系统中");
//				return response;
//			} else {
		// 1. check the serial number valid in the product table

		Brand brand = brandDaoImpl.get(product.getBrand().getBrand_ID(), true);
		if (brand.getChainStore() != null) {
			response.setFail("总部条码不能使用连锁店品牌 : " + brand.getBrand_Name());
			return response;
		}

		Category category = categoryDaoImpl.get(product.getCategory().getCategory_ID(), true);
		if (category.getChainId() == Category.TYPE_CHAIN) {
			response.setFail("总部条码不能使用连锁店种类 : " + category.getCategory_Name());
			return response;
		}

		if (serialNum != null && !serialNum.trim().equals("")) {
			Product product2 = productDaoImpl.getBySerialNum(serialNum, null);
			if (product2 == null) {
				response.setReturnCode(Response.FAIL);
				response.setMessage("此商品编码不存在于条码系统中");
				return response;
			} else if (!product.equals(product2)) {
				response.setReturnCode(Response.FAIL);
				response.setMessage("此商品编码的基础资料和以前所建基础资料不同");
				return response;
			}
		} else {

			List<Product> products = productDaoImpl.getProductsByProductCode(productCode, null);

			if (products != null && products.size() > 0) {
				for (Product product2 : products)
					productDaoImpl.initialize(product2);

				response.setReturnCode(Response.WARNING);
				response.setMessage("相同货号已经存在");
				response.setReturnValue(products);
				return response;
			}
		}

		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	/**
	 * this function is the headq scan the product information from sales order
	 * 
	 * @param barcode
	 * @param client_id
	 * @param skipJinsuan 0 : not skip, 1: skip
	 * @return
	 */
	@Transactional
	public ProductBarcode scanProductsByBarcodeHeadq(String barcode, int client_id, int storeId) {
		ProductBarcode productBarcode = productBarcodeDaoImpl.getByBarcode(barcode);
		if (productBarcode != null && (productBarcode.getStatus() == ProductBarcode.STATUS_OK || productBarcode.getStatus() == ProductBarcode.STATUS_NOT_PRODUCE)) {

			Product product = productBarcode.getProduct();

			// 1. get the qbefore from the SQLServer
			final String barcode_final = barcode;
			final int client_id_final = client_id;
			int qBefore = 0;
			int inventory = 0;
			qBefore = inventoryOrderDAOImpl.getQuantityBefore(productBarcode.getId(), client_id_final);

			productBarcode.setBoughtBefore(qBefore);

			// 1.1 get the current inventory
			inventory = headQInventoryStockDAOImpl.getProductStock(productBarcode.getId(), storeId, true);

			productBarcode.setCurrentInventory(inventory);

			// 2. get the sales history information
			int productId = productBarcode.getId();
			DetachedCriteria criteria_history = DetachedCriteria.forClass(HeadQSalesHistory.class, "salesHistory");
			criteria_history.add(Restrictions.eq("salesHistory.id.productId", productId));
			criteria_history.add(Restrictions.eq("salesHistory.id.clientId", client_id));
			List<HeadQSalesHistory> salesHistories = headQSalesHisDAOImpl.getByCritera(criteria_history, true);
			if (salesHistories != null && salesHistories.size() != 0) {
				HeadQSalesHistory headQSalesHistory = salesHistories.get(0);
				double salesPriceSelected = headQSalesHistory.getSalePriceSelected();
				double discountHistory = headQSalesHistory.getDiscount();
				double wholePrice = headQSalesHistory.getWholePrice();

				if (salesPriceSelected > 0 && discountHistory > 0 && wholePrice > 0) {
					product.setLastChoosePrice(salesPriceSelected);
					product.setLastInputPrice(wholePrice);
					product.setDiscount(discountHistory);
					productDaoImpl.evict(product);
				}
			}
		}

		return productBarcode;
	}

	public ProductBarcode getProductsByBarcode(String barcode) {

		ProductBarcode productBarcode = productBarcodeDaoImpl.getByBarcode(barcode);

		return productBarcode;
	}

	/**
	 * PDA获取产品信息
	 * 
	 * @param barcode
	 * @param clientId
	 * @return
	 */
	@Transactional
	public ProductBarcode getPDAProductsByBarcodeCalWholePrice(String barcode, int clientId) {
		// 1. get the product barcode
		ProductBarcode productBarcode = getProductsByBarcode(barcode);
		if (productBarcode != null) {
			productBarcode.getProduct().setLastChoosePrice(productBarcodeDaoImpl.getWholeSalePrice(productBarcode));

			// 2. get the qbefore from the SQLServer
			final String barcode_final = barcode;
			final int client_id_final = clientId;
			int qBefore = inventoryOrderDAOImpl.getQuantityBefore(productBarcode.getId(), client_id_final);
			productBarcode.setBoughtBefore(qBefore);
		}

		return productBarcode;
	}
	
	public List<ProductBarcode> getBarcodesInfoFromCriteria(ProductBarcode productBarcode, String brandIdString,
			Date startDate, Date endDate, String createDate) {
		List<ProductBarcode> barcodes = new ArrayList<ProductBarcode>();
		List<Integer> brandIds = Common_util.string2IntList(brandIdString);
		
		DetachedCriteria productBarcodeCriteria = DetachedCriteria.forClass(ProductBarcode.class);
		DetachedCriteria productCriteria = productBarcodeCriteria.createCriteria("product");

		if (productBarcode.getChainStore() != null && productBarcode.getChainStore().getChain_id() == 99)
			productBarcodeCriteria.add(Restrictions.isNull("chainStore"));
		else if (productBarcode.getChainStore() != null && productBarcode.getChainStore().getChain_id() == 0)
			productBarcodeCriteria.add(Restrictions.isNotNull("chainStore"));

		if (!productBarcode.getProduct().getProductCode().trim().equals(""))
			productCriteria.add(
					Restrictions.like("productCode", productBarcode.getProduct().getProductCode(), MatchMode.ANYWHERE));
		if (createDate != null && !createDate.equals("")) {
			java.util.Date endDate2 = new java.util.Date(endDate.getTime());
			endDate2.setHours(23);
			endDate2.setMinutes(59);
			endDate2.setSeconds(59);
			productBarcodeCriteria.add(Restrictions.between("createDate", startDate, endDate2));
		}
		if (!productBarcode.getBarcode().trim().equals(""))
			productBarcodeCriteria.add(Restrictions.eq("barcode", productBarcode.getBarcode()));

		if (productBarcode.getProduct().getArea().getArea_ID() != 0)
			productCriteria.add(Restrictions.eq("area.area_ID", productBarcode.getProduct().getArea().getArea_ID()));
		if (productBarcode.getProduct().getYear().getYear_ID() != 0)
			productCriteria.add(Restrictions.eq("year.year_ID", productBarcode.getProduct().getYear().getYear_ID()));
		if (productBarcode.getProduct().getQuarter().getQuarter_ID() != 0)
			productCriteria.add(
					Restrictions.eq("quarter.quarter_ID", productBarcode.getProduct().getQuarter().getQuarter_ID()));
		if (productBarcode.getProduct().getSizeMin() != 0)
			productCriteria.add(Restrictions.eq("sizeMin", productBarcode.getProduct().getSizeMin()));
		if (productBarcode.getProduct().getSizeMax() != 0)
			productCriteria.add(Restrictions.eq("sizeMax", productBarcode.getProduct().getSizeMax()));
		if (brandIds != null && brandIds.size() != 0) {
			if (brandIds.size() == 1)
				productCriteria.add(Restrictions.eq("brand.brand_ID", brandIds.get(0)));
			else
				productCriteria.add(Restrictions.in("brand.brand_ID", brandIds));			
		}

		if (productBarcode.getProduct().getCategoryLevel1().getCategory_ID() != 0)
			productCriteria.add(Restrictions.eq("categoryLevel1.category_ID",
					productBarcode.getProduct().getCategoryLevel1().getCategory_ID()));

		if (productBarcode.getProduct().getCategory().getCategory_ID() != 0)
			productCriteria.add(Restrictions.eq("category.category_ID",
					productBarcode.getProduct().getCategory().getCategory_ID()));

		Set<Integer> statusSet = new HashSet<Integer>();
		statusSet.add(ProductBarcode.STATUS_OK);
		statusSet.add(ProductBarcode.STATUS_NOT_PRODUCE);
	    productBarcodeCriteria.add(Restrictions.in("status", statusSet));

		barcodes = productBarcodeDaoImpl.getByCritera(productCriteria, true);

		return barcodes;
	}

	public Response getBarcodesFromCriteria(ProductBarcode productBarcode, String brandIdString,Integer belongTo2,
			Date startDate, Date endDate, String createDate,Integer page, Integer rowPerPage, String sort,
			String order) {
		
		Response response = new Response();
		List<ProductBarcodeVO> barcodeVos = new ArrayList<ProductBarcodeVO>();
		List<ProductBarcode> barcodes = new ArrayList<ProductBarcode>();

		DetachedCriteria productBarcodeCriteria = buildProductBarcodeCritera(productBarcode,brandIdString,belongTo2,startDate,endDate,createDate,page,rowPerPage,sort,order);
		DetachedCriteria totalProductBarcodeCriteria = buildProductBarcodeCritera(productBarcode,brandIdString,belongTo2,startDate,endDate,createDate,page,rowPerPage,sort,order);

		barcodes = productBarcodeDaoImpl.getByCritera(productBarcodeCriteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);
		totalProductBarcodeCriteria.setProjection(Projections.rowCount());
		int total = Common_util.getProjectionSingleValue(productBarcodeDaoImpl.getByCriteriaProjection(totalProductBarcodeCriteria, true));
		
		
		if (barcodes.size() != 0) {
			for (ProductBarcode pb : barcodes) {
				ProductBarcodeVO barcodeVO = new ProductBarcodeVO(pb,true);
				barcodeVos.add(barcodeVO);								
			}
		}
		
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("rows", barcodeVos);
		data.put("total", total);
		response.setReturnValue(data);
		
		return response;
	}
	
	public DetachedCriteria buildProductBarcodeCritera(ProductBarcode productBarcode, String brandIdString,Integer belongTo2,
			Date startDate, Date endDate, String createDate,Integer page, Integer rowPerPage, String sort,
			String order) {
		List<Integer> brandIds = Common_util.string2IntList(brandIdString);
		DetachedCriteria productBarcodeCriteria = DetachedCriteria.forClass(ProductBarcode.class);
		DetachedCriteria productCriteria = productBarcodeCriteria.createCriteria("product");
		DetachedCriteria brandCriteria = productCriteria.createCriteria("brand");
		

		if (productBarcode.getChainStore() != null && productBarcode.getChainStore().getChain_id() == 99)
			productBarcodeCriteria.add(Restrictions.isNull("chainStore"));
		else if (productBarcode.getChainStore() != null && productBarcode.getChainStore().getChain_id() == 0)
			productBarcodeCriteria.add(Restrictions.isNotNull("chainStore"));


		
		if (createDate != null && !createDate.equals("")) {
			java.util.Date endDate2 = new java.util.Date(endDate.getTime());
			endDate2.setHours(23);
			endDate2.setMinutes(59);
			endDate2.setSeconds(59);
			productBarcodeCriteria.add(Restrictions.between("createDate", startDate, endDate2));
		}
			if (!productBarcode.getProduct().getProductCode().trim().equals(""))
				productCriteria.add(
						Restrictions.like("productCode", productBarcode.getProduct().getProductCode(), MatchMode.ANYWHERE));
			
			if (!productBarcode.getBarcode().trim().equals(""))
				productBarcodeCriteria.add(Restrictions.eq("barcode", productBarcode.getBarcode()));
			if (StringUtils.isNotBlank(productBarcode.getProduct().getFactoryCode())) {
				productCriteria.add(Restrictions.like("factoryCode", productBarcode.getProduct().getFactoryCode(), MatchMode.ANYWHERE));
			}

			if (productBarcode.getProduct().getArea().getArea_ID() != 0)
				productCriteria.add(Restrictions.eq("area.area_ID", productBarcode.getProduct().getArea().getArea_ID()));
			if (productBarcode.getProduct().getYear().getYear_ID() != 0)
				productCriteria.add(Restrictions.eq("year.year_ID", productBarcode.getProduct().getYear().getYear_ID()));
			if (productBarcode.getProduct().getQuarter().getQuarter_ID() != 0)
				productCriteria.add(Restrictions.eq("quarter.quarter_ID", productBarcode.getProduct().getQuarter().getQuarter_ID()));
			if (productBarcode.getProduct().getSizeMin() != 0)
				productCriteria.add(Restrictions.eq("sizeMin", productBarcode.getProduct().getSizeMin()));
			if (productBarcode.getProduct().getSizeMax() != 0)
				productCriteria.add(Restrictions.eq("sizeMax", productBarcode.getProduct().getSizeMax()));
			if (brandIds != null && brandIds.size() != 0) {			
				if (brandIds.size() == 1)
					productCriteria.add(Restrictions.eq("brand.brand_ID", brandIds.get(0)));
				
				else
					productCriteria.add(Restrictions.in("brand.brand_ID", brandIds));
			}
			if (belongTo2 != Common_util.ALL_RECORD) {
				brandCriteria.add(Restrictions.eq("belong_To", belongTo2));
			}
							
			if (productBarcode.getProduct().getCategoryLevel1().getCategory_ID() != 0)
				productCriteria.add(Restrictions.eq("categoryLevel1.category_ID",
						productBarcode.getProduct().getCategoryLevel1().getCategory_ID()));

			if (productBarcode.getProduct().getCategory().getCategory_ID() != 0)
				productCriteria.add(Restrictions.eq("category.category_ID",
						productBarcode.getProduct().getCategory().getCategory_ID()));
		
			Set<Integer> statusSet = new HashSet<Integer>();
			statusSet.add(ProductBarcode.STATUS_OK);
			statusSet.add(ProductBarcode.STATUS_NOT_PRODUCE);
		productBarcodeCriteria.add(Restrictions.in("status", statusSet));
		return productBarcodeCriteria;
	}

	/**
	 * to delte the product barcode by id
	 * 
	 * @param productBarcodeId
	 * @return
	 */
	public Response deleteProductBarcode(int productBarcodeId) {
		Response response = new Response();
		ProductBarcode pb = productBarcodeDaoImpl.get(productBarcodeId, true);
		if (pb != null) {
			pb.setCreateDate(Common_util.getToday());
			pb.setStatus(ProductBarcode.STATUS_DELETE);
			productBarcodeDaoImpl.update(pb, true);
			response.setSuccess("删除成功");
		}else {
			response.setFail("未找到该条码信息");
		}
		return response;
	}

	@Transactional
	public Response updateProduct(File newImg,String fileName,ProductBarcode productBarcode,UserInfor loginUserInfor) {
		Response response = new Response();

		Product product = productDaoImpl.get(productBarcode.getProduct().getProductId(), true);
		if (product == null) {
			loggerLocal.info("Fail to get the product of productId : " + productBarcode.getProduct().getProductId());
			response.setFail("无法找到更新的产品");
		} else {
			ChainStore chainStore = product.getChainStore();
			if (chainStore != null) {
				response.setFail("总部不能修改连锁店条码");
				return response;
			}

			Brand brand = brandDaoImpl.get(product.getBrand().getBrand_ID(), true);
			if (brand.getChainStore() != null) {
				response.setFail("总部条码不能使用连锁店品牌 : " + brand.getBrand_Name());
				return response;
			}
			if (productBarcode.getColor().getColorId() != 0) {
				//校验颜色是否是数据库存在的合法颜色
				Color color = colorDaoImpl.get(productBarcode.getColor().getColorId(), true);
				if (color == null) {
					response.setFail("非法货品颜色,请重新选择颜色" + brand.getBrand_Name());
					return response;
				}

			}else {
				productBarcode.setColor(null);
			}
			
			Product newProduct = productBarcode.getProduct();
						
			product.setNumPerHand(newProduct.getNumPerHand());
			product.setProductCode(newProduct.getProductCode());
			product.setSalesPrice(newProduct.getSalesPrice());
			product.setRecCost(newProduct.getRecCost());
			// product.setRecCost2(newProduct.getRecCost2());
			product.setWholeSalePrice(newProduct.getWholeSalePrice());
			product.setWholeSalePrice2(newProduct.getWholeSalePrice2());
			product.setWholeSalePrice3(newProduct.getWholeSalePrice3());
			product.setUnit(newProduct.getUnit());
			product.setSalesPriceFactory(newProduct.getSalesPriceFactory());
			product.setCategoryLevel1(newProduct.getCategoryLevel1());
			product.setCategory(newProduct.getCategory());
			product.setYear(newProduct.getYear());
			product.setQuarter(newProduct.getQuarter());
			//注意： 这里需要查询一次，否则会报：object references an unsaved transient instance - save the transient instance before flushing:  
			Brand brand2 = brandDaoImpl.get(newProduct.getBrand().getBrand_ID(), true);
			if (brand2 != null) {
				product.setBrand(brand2);
			}			
			double discount = newProduct.getDiscount();
			if (discount <= 0 || discount > 1)
				product.setDiscount(1);
			else
				product.setDiscount(newProduct.getDiscount());
			product.setCreateDate(Common_util.getLastUpdateTimeInterval());

			String material = newProduct.getMaterial();
			if (material.equals(""))
				product.setMaterial(material);
			else
				product.setMaterial(newProduct.getMaterial());
			product.setSizeMin(newProduct.getSizeMin());

			product.setSizeMax(newProduct.getSizeMax());
			product.setCostMultiple(newProduct.getCostMultiple());
			product.setFactoryCode(newProduct.getFactoryCode());
			
			product.setLastUpdateBy(loginUserInfor.getUser_name());
			product.setLastUpdateTime(Common_util.getToday());
			productDaoImpl.saveOrUpdate(product, true);			
			ProductBarcode barcode =productBarcodeDaoImpl.getByProductBarcode(productBarcode.getBarcode());
			if (barcode != null ) {
				barcode.setColor(productBarcode.getColor());
				barcode.setLastUpdateBy(loginUserInfor.getUser_name());
				barcode.setLastUpdateTime(Common_util.getToday());
				productBarcodeDaoImpl.update(barcode, true);	
				response.setSuccess("条码更新成功");
			}else {
				response.setFail("无法找到更新的条码信息");
			}
			
		}
		
		

		return response;
	}



	/**
	 * to check whether the barcode is used or not
	 * 
	 * @param barcode
	 * @return
	 */
	public boolean checkBarcodeInOrder(int productBarcodeId) {

		int count = inventoryOrderProductDAOImpl.checkBarcodeInOrder(productBarcodeId);

		if (count > 0)
			return true;
		else
			return false;
	}

	/**
	 * to generate the barcode excel report which is to send to
	 * 
	 * @param selectedBarcodes
	 * @param templatePath
	 * @return
	 */
	@Transactional
	public Map<String, Object> generateExcelReport(String barcodes, String templatePath) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		List<String> selectedBarcodes = new ArrayList<String>();
		String[] bs = barcodes.split(",");
		if (bs.length >0) {
			for (int i = 0; i < bs.length; i++) {
				selectedBarcodes.add(bs[i]);
			}
		}
		ByteArrayInputStream byteArrayInputStream;
		try {
			HSSFWorkbook wb = null;
			List<ProductBarcode> products = new ArrayList<ProductBarcode>();			

			if (selectedBarcodes != null && selectedBarcodes.size() > 0) {
				DetachedCriteria productCriteria = DetachedCriteria.forClass(ProductBarcode.class, "p");
				productCriteria.add(Restrictions.in("p.barcode", selectedBarcodes));

				products = productBarcodeDaoImpl.getByCritera(productCriteria, true);
			}

			BarcodeTemplate barcodeTemplate = new BarcodeTemplate(products, templatePath);

			wb = barcodeTemplate.process();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			try {
				wb.write(os);
			} catch (IOException e) {
				e.printStackTrace();
			}
			byte[] content = os.toByteArray();
			byteArrayInputStream = new ByteArrayInputStream(content);
			returnMap.put("stream", byteArrayInputStream);

			return returnMap;
		} catch (Exception ex) {
			loggerLocal.error(ex);
		}
		return null;
	}

	/**
	 * to synchronize the price with the sql server in jin suan
	 * 
	 * @param selectedBarcodes
	 * @return
	 */
	public Map<String, String> synchronizePrice(String barcodes,List<ProductBarcode> productBarcodes,UserInfor loginUserInfor) {
			Set<String> selectedBarcodes = new HashSet<String>();
			String[] bs = barcodes.split(",");
			if (bs.length >0) {
				for (int i = 0; i < bs.length; i++) {
					selectedBarcodes.add(bs[i]);
					
				}
				
			}
			String ERROR_PRICE_INCONSISTANT = "";
			String ERROR_NOT_FOUND = "";
			String ERROR_PRODUCT_CODE_INCONSISTANT = "";

			HashMap<String, ProductsMS> productMSMap = productsMSImpl.retrieveProducts(selectedBarcodes);

			DetachedCriteria productCriteria = DetachedCriteria.forClass(ProductBarcode.class);
			productCriteria.add(Restrictions.in("barcode", selectedBarcodes));

			/**
			 * to get the barcodes
			 */
			List<ProductBarcode> products = productBarcodeDaoImpl.getByCritera(productCriteria, true);
			HashMap<String, ProductBarcode> productMap = new HashMap<String, ProductBarcode>();
			for (ProductBarcode product : products) {
				productMap.put(product.getBarcode(), product);
			}

			for (String barcode : selectedBarcodes) {
				try {
					ProductsMS productMS = productMSMap.get(barcode);
					ProductBarcode productBarcode = productMap.get(barcode);
					Product product = productBarcode.getProduct();
					Color color = productBarcode.getColor();
					String colorS = "";
					if (color != null)
						colorS = color.getName();

					if (productMS == null) {
						ERROR_NOT_FOUND += barcode + ",";
					} else {
						String productCode_mis = product.getProductCode();
						String productCode_ms = productMS.getProductCode();

						if (!productCode_ms.equals(productCode_mis + colorS))
							ERROR_PRODUCT_CODE_INCONSISTANT += barcode + "(" + productCode_mis + colorS + ","
									+ productMS.getProductCode() + "),";
						else {
							PriceMS priceMS = productMSMap.get(barcode).getPrice();
							double glprice = priceMS.getGlprice();
							double recPrice = priceMS.getRecprice();
							double wholePrice1 = priceMS.getPrice1();
							double wholePrice2 = priceMS.getPrice2();
							double wholePrice3 = priceMS.getPrice3();

							double discount = productMSMap.get(barcode).getDiscount();
							double retailPriceFactory = priceMS.getRetailprice();

//	     			        BigDecimal decimal = new BigDecimal(discount * retailPrice_factory);
//	     			        double wholePrice_by_calculate = decimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
							double glprice_org = product.getSalesPrice();
							double recPrice_org = product.getRecCost();
							double wholePrice1_org = product.getWholeSalePrice();
							double wholePrice2_org = product.getWholeSalePrice2();
							double wholePrice3_org = product.getWholeSalePrice3();
							double discount_org = product.getDiscount();
							double retailPriceFactory_org = product.getSalesPriceFactory();

							boolean valid = true;

							if (glprice_org != 0 && glprice_org != glprice) {
								ERROR_PRICE_INCONSISTANT += barcode + "(零售价," + glprice_org + "," + glprice + "),";
								valid = false;
							}
							if (recPrice_org != 0 && recPrice_org != recPrice) {
								ERROR_PRICE_INCONSISTANT += barcode + "(进价," + recPrice_org + "," + recPrice + "),";
								valid = false;
							}
							if (wholePrice1_org != 0 && wholePrice1_org != wholePrice1) {
								ERROR_PRICE_INCONSISTANT += barcode + "(批发价1," + wholePrice1_org + "," + wholePrice1 + "),";
								valid = false;
							}
							if (wholePrice2_org != 0 && wholePrice2_org != wholePrice2) {
								ERROR_PRICE_INCONSISTANT += barcode + "(批发价2," + wholePrice2_org + "," + wholePrice2 + "),";
								valid = false;
							}
							if (wholePrice3_org != 0 && wholePrice3_org != wholePrice3) {
								ERROR_PRICE_INCONSISTANT += barcode + "(批发价3," + wholePrice3_org + "," + wholePrice3 + "),";
								valid = false;
							}
							if (discount_org != 0 && discount_org != 1 && discount_org != discount) {
								ERROR_PRICE_INCONSISTANT += barcode + "(折扣," + discount_org + "," + discount + "),";
								valid = false;
							}
							if (retailPriceFactory_org != 0 && retailPriceFactory_org != retailPriceFactory) {
								ERROR_PRICE_INCONSISTANT += barcode + "(厂家零售价," + retailPriceFactory_org + ","
										+ retailPriceFactory + "),";
								valid = false;
							}
							if (valid) {
								product.setSalesPrice(glprice);
								product.setRecCost(recPrice);
								product.setWholeSalePrice(wholePrice1);
								product.setWholeSalePrice2(wholePrice2);
								product.setWholeSalePrice3(wholePrice3);
								product.setDiscount(discount);
								product.setSalesPriceFactory(retailPriceFactory);
								product.setLastUpdateBy(loginUserInfor.getUser_name());
								product.setLastUpdateTime(Common_util.getToday());
								productDaoImpl.saveOrUpdate(product, true);
							}
						}
					}
				} catch (Exception e) {
					loggerLocal.error("BarcodeService.synchronizePrice（），barcode : " + barcode + " can't be found");
					ERROR_NOT_FOUND += barcode + ",";
				}
			}

			Map<String, String> msgMap = new HashMap<String, String>();
			msgMap.put(Common_util.ERROR_NOT_FOUND, ERROR_NOT_FOUND);
			msgMap.put(Common_util.ERROR_PRICE_INCONSISTANT, ERROR_PRICE_INCONSISTANT);
			msgMap.put(Common_util.ERROR_PRODUCT_CODE_INCONSISTANT, ERROR_PRODUCT_CODE_INCONSISTANT);

			return msgMap;		
	}

	/**
	 * to generate the product and the barcodes
	 * 
	 * @param barCode
	 * @throws Exception
	 */
	@Transactional
	public Response saveProduct(Product product, List<Integer> colors, List<Integer> sizes,UserInfor loginUserInfor) {
		Response response = new Response();
		String serialNum = product.getSerialNum();

		product.setCreateBy(loginUserInfor.getUser_name());
		product.setCreateDate(Common_util.getToday());
		product.setLastUpdateBy(loginUserInfor.getUser_name());
		product.setLastUpdateTime(Common_util.getToday());
		/**
		 * 3.0 if it is existing product, no need to save information again, save the
		 * product information
		 */
		if (serialNum == null || serialNum.trim().equals("")) {
			double discount = product.getDiscount();
			if (discount <= 0 || discount > 1)
			product.setDiscount(1);
			product.setCreateBy(loginUserInfor.getUser_name());
			product.setCreateDate(Common_util.getToday());
			//生成Product identtity
			response = generateProductIdentity(product);
			if (!response.isSuccess())
				return response;
			
			productDaoImpl.save(product, true);	
			product.setSerialNum(String.valueOf(product.getProductId()));
			product.setLastUpdateBy(loginUserInfor.getUser_name());
			product.setLastUpdateTime(Common_util.getToday());
			productDaoImpl.update(product, true);
		} else {
			product = productDaoImpl.getBySerialNum(serialNum, null);
		}

		/**
		 * 4.0 generate the barcode
		 */
		generateProductBarcodes(product, colors, sizes,null,loginUserInfor);

		/**
		 * 5.0 保存year 和quarter以备以后使用
		 */
		int yearId = product.getYear().getYear_ID();
		int quarterId = product.getQuarter().getQuarter_ID();
		HeadQInputHelp headQInputHelp = headQInputHelpDaoImpl.getCreateProductHelp();
		if (headQInputHelp != null) {
			headQInputHelp.setYear(yearId);
			headQInputHelp.setQuarter(quarterId);
			headQInputHelpDaoImpl.saveOrUpdate(headQInputHelp, true);
		} else {
			headQInputHelp = new HeadQInputHelp();
			headQInputHelp.setYear(yearId);
			headQInputHelp.setQuarter(quarterId);
			headQInputHelpDaoImpl.save(headQInputHelp, true);
		}

		response.setReturnCode(Response.SUCCESS);
		response.setMessage("成功生成条形码");

		return response;
	}
	
	
	/**
	 * 生成公司内部货号信息
	 * 
	 * 更新product identity sequence 表数据
	 * @param product
	 * @return
	 */
	private synchronized Response generateProductIdentity(Product product) {
		Response response = new Response();
		String productIdentity = "";
		Year year = yearDaoImpl.get(product.getYear().getYear_ID(), true);
		Quarter quarter = quarterDaoImpl.get(product.getQuarter().getQuarter_ID(), true);
		Category categoryLevel = categoryDaoImpl.get(product.getCategoryLevel1().getCategory_ID(), true);
		Category category = categoryDaoImpl.get(product.getCategory().getCategory_ID(), true);
		productIdentity += year.getYear_Code() + quarter.getQuarter_Code() + categoryLevel.getCategory_Code()
				+ category.getCategory_Code();

		ProductIdentitySequence pis = productIsDaoImpl.getSequence(year.getYear_ID(),quarter.getQuarter_ID(),categoryLevel.getCategory_ID(),category.getCategory_ID());
		if (pis == null) {

            pis = new ProductIdentitySequence();
            pis.setCategoryLevel1Id(categoryLevel.getCategory_ID());
            pis.setCateogryId(category.getCategory_ID());
            pis.setQuarterId(quarter.getQuarter_ID());
            pis.setYearId(year.getYear_ID());
            pis.setSequence(1);
            productIsDaoImpl.save(pis, true);
		}else {
			pis.setSequence(pis.getSequence()+1);
			productIsDaoImpl.update(pis, true);
		}

		productIdentity += Common_util.formatCode(pis.getSequence(), 3);
		
		//验证Product identity没有重复
		if (productDaoImpl.getCountOfProductIdentity(productIdentity)>0) {
			response.setFail("当前产品出现identity重复现象，请联系系统管理员 : " + productIdentity);
			return response;
		}

		product.setProductIdentity(productIdentity);
		return response;
	}
	
	
	/**
	 * 5.0 get the same group product infromation
	 */
	@Transactional
	public Response getSameGroupProductBarcodes(Product product) {
		Response response = new Response();
		List<ProductBarcodeVO> barcodeVos = new ArrayList<ProductBarcodeVO>();
		List<ProductBarcode> barcodes = productBarcodeDaoImpl.getProductBracodeFromSameGroup(product, null);
		for (ProductBarcode barcode : barcodes) {
			productBarcodeDaoImpl.initialize(barcode);
			ProductBarcodeVO barcodeVO = new ProductBarcodeVO(barcode,true);
			barcodeVos.add(barcodeVO);
		
		}

		Map<String, Object> data = new HashMap<String, Object>();
		data.put("rows", barcodeVos);
			
		response.setReturnValue(data);
		return response;
	}

	/**
	 * 
	 * @param product
	 * @param colors
	 * @param sizes
	 */
	private void generateProductBarcodes(Product product, List<Integer> colorIds, List<Integer> sizeIds,ChainStore chainStore,UserInfor loginUserInfor) {
		List<Color> colors = new ArrayList<Color>();
		List<Size> sizes = new ArrayList<Size>();

		if (colorIds == null || colorIds.size() == 0)
			colors.add(null);
		else {
			for (Integer colorId : colorIds) {
				if (colorId != 0)
					colors.add(new Color(colorId));
			}
		}

		if (sizeIds == null || sizeIds.size() == 0)
			sizes.add(null);
		else {
			for (Integer sizeId : sizeIds) {
				if (sizeId != 0)
					sizes.add(new Size(sizeId));
			}
		}

		List<ProductBarcode> productBarcodes = productBarcodeDaoImpl.getBarcodeFromProduct(product.getProductId());
		List<ProductBarcode> deletedProductBarcodes = new ArrayList<ProductBarcode>();
		for (ProductBarcode barcode : productBarcodes) {
			if (barcode.getStatus() == ProductBarcode.STATUS_DELETE)
				deletedProductBarcodes.add(barcode);
		}

		for (Color color : colors) {
			for (Size size : sizes) {
				// save the productBarcode information
				ProductBarcode productBarcode = new ProductBarcode(product, color, size);
				productBarcode.setCreateBy(loginUserInfor.getUser_name());
				productBarcode.setCreateDate(Common_util.getToday());
				
				if (productBarcodes.contains(productBarcode)) {
					if (deletedProductBarcodes.contains(productBarcode)) {
						for (ProductBarcode pBarcode : deletedProductBarcodes) {
							if (pBarcode.equals(productBarcode)) {
								pBarcode.setStatus(ProductBarcode.STATUS_OK);
								pBarcode.setLastUpdateBy(loginUserInfor.getUser_name());
								pBarcode.setLastUpdateTime(Common_util.getToday());
								productBarcodeDaoImpl.update(pBarcode, true);
							}
						}
					}
				} else {
					productBarcode.setCreateBy(loginUserInfor.getUser_name());
					productBarcode.setCreateDate(Common_util.getToday());
					
					productBarcodeDaoImpl.save(productBarcode, true);

					// generate the barcode
					int id = productBarcode.getId();
					String barcode = "";
					if (chainStore == null) {
						 barcode = generateBarcode(id, null);
					}else {
						 barcode = generateBarcode(id, chainStore);
					}					
					productBarcode.setBarcode(barcode);
					productBarcode.setLastUpdateBy(product.getLastUpdateBy());
					productBarcode.setLastUpdateTime(Common_util.getToday());
					productBarcodeDaoImpl.update(productBarcode, true);
				}
			}
		}

	}

	/**
	 * function to generate the product barcodes
	 * 
	 * @param productId
	 * @param colorGroupId
	 * @param sizeGroupId
	 * @todo 弃用管家婆以后的方案
	 */
//	private synchronized void generateProductBarcodes(Product product , int colorGroupId, int sizeGroupId){
//		List<ColorGroups> colorGroups = new ArrayList<ColorGroups>();
//		List<SizeGroups> sizeGroups = new ArrayList<SizeGroups>();
//		if (colorGroupId != 0){
//			colorGroups = colorMSGroupsDAOImpl.getByColorGroupId(colorGroupId);
//		} else {
//			colorGroups.add(ColorGroups.dummy);
//		}
//		if (sizeGroupId != 0){
//			sizeGroups = sizeMSGroupsDAOImpl.getBySizeGroupId(sizeGroupId);
//		} else {
//			sizeGroups.add(SizeGroups.dummy);
//		}
//		
//		for (ColorGroups colorGroup: colorGroups){
//			int colorId = colorGroup.getColorId();
//			Color color = null;
//			if (colorId != 0){
//                color = colorMSDAOImpl.get(colorId, true);
//			}
//			
//			for (SizeGroups sizeGroup: sizeGroups){
//				int sizeId = sizeGroup.getSizeId();
//				Size size = null;
//				if (sizeId != 0){
//					size = sizeMSDAOImpl.get(sizeId, true);
//				}
//				
//				//save the productBarcode information
//				ProductBarcode productBarcode = new ProductBarcode(product, color, size);
//				productBarcodeDaoImpl.save(productBarcode, true);
//				
//				//generate the barcode
//				int id = productBarcode.getId();
//				String barcode = generateBarcode(id);
//				productBarcode.setBarcode(barcode);
//				productBarcodeDaoImpl.update(productBarcode, true);
//			}
//		}
//		
//	}

	/**
	 * logic of barcode odd total = odd number * 3 even total = even number total =
	 * odd total + even total check number = 10 - total % 10 barcode = barcode11 +
	 * check number
	 * 
	 * 千禧 1开头 千禧客户9开头 喜乐3开头 喜乐客户7开头
	 * 
	 * @param barCode
	 * @return
	 */
	public final static String generateBarcode(int sequenceId, ChainStore chainStore) {
		StringBuffer prefix = null;

		// 自己做的条码从3开始
		if (chainStore == null)
			prefix = new StringBuffer("1");
		else
			prefix = new StringBuffer("9");

		String productIdS = String.valueOf(sequenceId);
		int prefixLength = 11 - productIdS.length();

		prefixLength = prefixLength - prefix.length();
		// for the others add 0 or random number to the barcode
		Random random = new Random(new Date().getTime());
		for (int i = 0; i < prefixLength; i++) {
			// for the first two digits, we need the random number
			if (i < 2)
				prefix.append(random.nextInt(10));
			else
				prefix.append("0");
		}

		productIdS = prefix.toString() + productIdS;

		char[] codeArray = productIdS.toCharArray();

		List<Integer> intArray = new ArrayList<Integer>();
		for (char code : codeArray) {
			intArray.add(Integer.parseInt(String.valueOf(code)));
		}
		int totalOfOdd = 0;
		for (int i = 0; i < intArray.size(); i = i + 2) {
			totalOfOdd += intArray.get(i);
		}
		totalOfOdd *= 3;

		int totalOfEven = 0;
		for (int i = 1; i < intArray.size(); i = i + 2) {
			totalOfEven += intArray.get(i);
		}

		int total = totalOfEven + totalOfOdd;

		int remain = total % 10;

		if (remain != 0)
			remain = 10 - remain;

		return productIdS + remain;
	}

	/**
	 * to get the product sales information from sales history
	 * 
	 * @param barcode
	 * @param client_id
	 * @return
	 * @throws Exception
	 */
	public ProductBarcode getProductFromSalesHistory(String barcode, int client_id, int storeId) {
		ProductBarcode productBarcode = productBarcodeDaoImpl.getByBarcode(barcode);

		if (productBarcode != null) {
			Product product = productBarcode.getProduct();
			int productId = productBarcode.getId();

			int inventoryLevel = 0;
			try {
				inventoryLevel = headQInventoryStockDAOImpl.getProductStock(productBarcode.getId(), storeId, true);
				//inventoryLevel = getProductInven(barcode, ProductsMSDAOImpl.MENGYANG_STORE_ID);
			} catch (Exception e) {
				e.printStackTrace();
			}
			productBarcode.setCurrentInventory(inventoryLevel);

			HeadQSalesHistoryId headQSalesHistoryId = new HeadQSalesHistoryId(productId, client_id);
			HeadQSalesHistory salesHistory = headQSalesHisDAOImpl.get(headQSalesHistoryId, true);

			if (salesHistory != null) {
				product.setRecCost(salesHistory.getRecCost());
				product.setSalesPrice(salesHistory.getSalesPrice());
				product.setDiscount(salesHistory.getDiscount());
				product.setLastChoosePrice(salesHistory.getSalePriceSelected());
				product.setLastInputPrice(salesHistory.getWholePrice());
				productBarcode.setIsDaimai(salesHistory.getIsDaimai());
				productBarcode.setIsMaiduan(salesHistory.getIsMaiduan());
			} else {
				product.setRecCost(0);
				product.setSalesPrice(0);
				product.setLastInputPrice(0);
				product.setDiscount(0);
			}

			return productBarcode;
		} else
			return productBarcode;
	}

	/**
	 * this function is to generate the Jinsuan excel report
	 * 
	 * @param selectedBarcodes
	 * @param string
	 * @return
	 */
	@Transactional
	public Map<String, Object> generateJinsuanExcelReport(String barcodes,String templatePosition) {
		Set<String> barSet = new HashSet<String>();
		String[] bs = barcodes.split(",");
		if (bs.length >0) {
			for (int i = 0; i < bs.length; i++) {
				barSet.add(bs[i]);				
			}			
		}
		List<ProductBarcode> products = productBarcodeDaoImpl.getProductBarcodes(barSet);

		InventoryOrder order = new InventoryOrder();
		Set<InventoryOrderProduct> inventoryOrderProducts = order.getProduct_Set();
		for (ProductBarcode product : products) {
			InventoryOrderProduct orderProduct = new InventoryOrderProduct();
			orderProduct.setProductBarcode(product);
			inventoryOrderProducts.add(orderProduct);
		}

		Map<String, Object> returnMap = new HashMap<String, Object>();

		ByteArrayInputStream byteArrayInputStream;
		try {
			HSSFWorkbook wb = null;
			JinSuanOrderTemplate orderTemplate = new JinSuanOrderTemplate(order, templatePosition);
			wb = orderTemplate.process();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			try {
				wb.write(os);
			} catch (IOException e) {
				loggerLocal.error(e);
			}
			byte[] content = os.toByteArray();
			byteArrayInputStream = new ByteArrayInputStream(content);
			returnMap.put("stream", byteArrayInputStream);

			return returnMap;
		} catch (Exception ex) {
			loggerLocal.error(ex);
		}
		return null;
	}
	
	/**
	 * this function is to generate the Jinsuan excel report
	 * 
	 * @param selectedBarcodes
	 * @param string
	 * @return
	 */
	@Transactional
	public Map<String, Object> generatePurchaseExcelReport(Integer orderId,String templatePosition) {

		PurchaseOrder purchaseOrder = new PurchaseOrder();
		List<PurchaseOrderProduct> list = purchaseOrderProductDaoImpl.selectPurchaseOrderProducts(orderId, true);

		purchaseOrder.setProductList(list);
		Map<String, Object> returnMap = new HashMap<String, Object>();

		ByteArrayInputStream byteArrayInputStream;
		try {
			HSSFWorkbook wb = null;

			JinSuanOrderTemplate orderTemplate = new JinSuanOrderTemplate(purchaseOrder, templatePosition);
			wb = orderTemplate.processPurchase();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			try {
				wb.write(os);
			} catch (IOException e) {
				loggerLocal.error(e);
			}
			byte[] content = os.toByteArray();
			byteArrayInputStream = new ByteArrayInputStream(content);
			returnMap.put("stream", byteArrayInputStream);

			return returnMap;
		} catch (Exception ex) {
			loggerLocal.error(ex);
		}
		return null;
	}

	/**
	 * search the brands by the brandName
	 * 
	 * @param brand_Name
	 */
	public List<Brand> searchBrands(String brand_Name) {
		DetachedCriteria criteria = DetachedCriteria.forClass(Brand.class);

		criteria.add(Restrictions.or(Restrictions.like("brand_Name", "%" + brand_Name + "%"),
				Restrictions.like("comment", "%" + brand_Name + "%")));

		criteria.addOrder(Order.asc("brand_Name"));

		return brandDaoImpl.getByCritera(criteria, true);

	}

	/**
	 * Function to get the product inventory from JinSuan
	 * 
	 * @todo 未来库存正确后需要修改
	 * @param barcode
	 * @return
	 */
//	public int getProductInven(String serialNum, Integer storeId) {
//		11
//		ProductsMS productsMS = productsMSImpl.getBySerialNum(serialNum);
//
//		if (productsMS == null)
//			return 0;
//		else {
//			int productId = productsMS.getProductID();
//
//			int storeIdInt = ProductsMSDAOImpl.MENGYANG_STORE_ID;
//			if (storeId != null)
//				storeIdInt = storeId;
//			Object[] values = new Object[] { storeIdInt, productId, 0, 0, 0 };
//
//			List<Object> inventoryObj = null;
//
//			inventoryObj = productsMSImpl.executeProcedure(ProductsMSDAOImpl.GET_INVENTORY_PROCEDURE, values);
//
//			if (inventoryObj != null && inventoryObj.size() == 1)
//				return (int) Common_util.getDouble(inventoryObj.get(0));
//			else
//				return 0;
//		}
//	}

	public static JSONObject transferProductBarcode(Map<String, Object> jsonMap, JsonConfig jsonConfig) {
		if (jsonConfig == null)
			jsonConfig = new JsonConfig();

		JSONObject jsonObject = new JSONObject();
		jsonConfig.registerJsonValueProcessor(java.util.Date.class, new JSONUtilDateConverter());
		try {
			jsonObject = JSONObject.fromObject(jsonMap, jsonConfig);
		} catch (Exception e) {
			e.printStackTrace();
			loggerLocal.error(e);
		}
		return jsonObject;
	}

	/**
	 * 转化product barcode 成 vo
	 * 
	 * @param barcode_org
	 * @return
	 */
	public Map formatProductBarcodeVO(List<ProductBarcode> barcode_org) {
		Map dataMap = new HashMap();
		List<ProductBarcodeVO> barcodeVOs = new ArrayList<ProductBarcodeVO>();
		if (barcode_org != null) {
			for (ProductBarcode barcode : barcode_org) {
				ProductBarcodeVO productBarcodeVO = new ProductBarcodeVO(barcode);
				barcodeVOs.add(productBarcodeVO);
			}
		}

		dataMap.put("rows", barcodeVOs);
		return dataMap;
	}

	/**
	 * to search color
	 * 
	 * @param colorNames
	 * @return
	 */
	public List<Color> searchColors(String colorNames) {
		List<Color> colors = new ArrayList<Color>();

		if (colorNames != null && !colorNames.trim().equals("")) {
			String[] colorArray = colorNames.split("-");
			List<String> colorNameList = Arrays.asList(colorArray);

			colors = colorDaoImpl.getColors(colorNameList);
		}
		return colors;
	}

	/**
	 * 通过serial number获取产品信息
	 * 
	 * @param serialNum
	 * @return
	 */
	public Response getProductInforBySerialNum(String serialNum) {
		Response response = new Response();

		Product product = productDaoImpl.getBySerialNum(serialNum, null);

		if (product == null) {
			response.setMessage("找不到产品信息");
			response.setReturnCode(Response.FAIL);
			return response;
		}

		int productId = product.getProductId();
		List<ProductBarcode> productBarcodes = productBarcodeDaoImpl.getBarcodeFromProduct(productId);

		String colors = "";
		if (productBarcodes != null && productBarcodes.size() > 0) {
			for (ProductBarcode productBarcode : productBarcodes)
				if (productBarcode.getColor() != null)
					colors += productBarcode.getColor().getName() + " ";
		}

		Map dataMap = new HashMap<String, Object>();
		dataMap.put("product", product);
		dataMap.put("color", colors);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);

		return response;
	}

	public void prepareCreateProductUIForm(ProductActionFormBean formBean) {
		HeadQInputHelp headQInputHelp = headQInputHelpDaoImpl.getCreateProductHelp();
		if (headQInputHelp != null) {
			formBean.getProductBarcode().getProduct().getYear().setYear_ID(headQInputHelp.getYear());
			formBean.getProductBarcode().getProduct().getQuarter().setQuarter_ID(headQInputHelp.getQuarter());
		}

	}

	/**
	 * 批量删除条码
	 * 
	 * @param inventory
	 */
	@Transactional
	public Response batchDeleteBarcode(File inventory) {
		Response response = new Response();

		BarcodeTemplate barcodeTemplate = new BarcodeTemplate(inventory);
		List<String> barcodes = barcodeTemplate.proccess();

		if (barcodes == null) {
			response.setFail("读取文件出现问题,请检查文件系统");
		} else {
			if (barcodes.size() > 0) {
				String queryString = "UPDATE ProductBarcode p SET p.status = " + ProductBarcode.STATUS_DELETE
						+ " where p.barcode in ";

				String variables = "('" + barcodes.get(0);

				for (int i = 1; i < barcodes.size(); i++) {
					variables += "','" + barcodes.get(i);
				}

				queryString += variables + "')";

				int numberOfDelete = productBarcodeDaoImpl.executeHQLUpdateDelete(queryString, null, true);

				response.setSuccess("文件上需要删除 " + barcodes.size() + " 个条码. 实际删除了 " + numberOfDelete + " 个条码");

			} else {
				response.setFail("没有条码需要删除，请检查文件");
			}
		}

		return response;

	}

	/**
	 * 批量新增条码
	 * 
	 * @param inventory
	 */
	@Transactional
	public Response batchInsertBarcode(File inventory, Product product,UserInfor loginUserInfor) {
		Response response = new Response();
		/**
		 * 1. 服务器端验证, 年份, 季度，品牌不能为空，并且 品牌不能是连锁店自己新增品牌
		 */
		Area area = areaDaoImpl.get(Area.CURRENT_AREA, true);
		Year year = yearDaoImpl.get(product.getYear().getYear_ID(), true);
		Quarter quarter = quarterDaoImpl.get(product.getQuarter().getQuarter_ID(), true);
		Brand brand = brandDaoImpl.get(product.getBrand().getBrand_ID(), true);
		if (year == null)
			response.setFail("产品年份不能为空, 请检查");
		else if (quarter == null)
			response.setFail("产品季度不能为空, 请检查");
		else if (brand == null)
			response.setFail("产品品牌不能为空, 请检查");
		else if (brand.getChainStore() != null) {
			response.setFail("产品品牌不能是连锁店品牌, 请检查");
		}

		BarcodeImportTemplate barcodeTemplate = new BarcodeImportTemplate(inventory, year, quarter, brand, area);
		barcodeTemplate.proccess(categoryDaoImpl, colorDaoImpl, productUnitDaoImpl);

		if (!barcodeTemplate.isSuccess()) {
			response.setFail(barcodeTemplate.getValidateMsg());
		} else {
			List<Object> wsData = barcodeTemplate.getWsData();
			if (wsData == null || wsData.size() == 0) {
				response.setFail("这个表格无数据");
			} else {

				int barCodeSize = 0;

				for (Object rowData : wsData) {
					List<Object> rowDataList = (List<Object>) rowData;
					Product product2 = (Product) rowDataList.get(0);
					List<Integer> colorIds = (List<Integer>) rowDataList.get(1);

					saveProduct(product2, colorIds, null,loginUserInfor);
				}
				response.setSuccess("成功导入 " + wsData.size() + "个 产品 . 条码信息 : " + year.getYear() + quarter.getQuarter_Name() + " " + brand.getBrand_Name());
			}

		}

		return response;
	}

	public void prepareBatchInsertBarcodeUI(ProductActionFormBean formBean, ProductActionUIBean uiBean) {
		List<Year> years = yearDaoImpl.getLatestYears();
		List<Quarter> quarters = quarterDaoImpl.getAll(true);

		uiBean.getBasicData().setQuarterList(quarters);
		uiBean.getBasicData().setYearList(years);

	}

	/**
	 * 进行批量条码修改
	 * 
	 * @param inventory`
	 * @return
	 * @throws Exception
	 */
	@Transactional
	public Response batchUpdateBarcode(File inventory) {
		Response response = new Response();

		try {
			BarcodeUpdateTemplate barcodeTemplate = new BarcodeUpdateTemplate(inventory);
			barcodeTemplate.proccess(yearDaoImpl,quarterDaoImpl,productBarcodeDaoImpl, categoryDaoImpl, productUnitDaoImpl,productDaoImpl);

			if (!barcodeTemplate.isSuccess()) {
				response.setFail(barcodeTemplate.getValidateMsg());
			} else {
				Set<Product> wsData = barcodeTemplate.getWsData();
				if (wsData == null || wsData.size() == 0) {
					response.setFail("无法找到更新数据");
				} else {

					for (Product rowData : wsData) {
						rowData.setCreateDate(Common_util.getToday());						
						productDaoImpl.update(rowData, true);
					}
					response.setSuccess("成功更新 " + wsData.size() + "个 产品信息。");
				}
			}
		} catch (Exception e) {
			response.setFail("更新条码失败: " + e.getMessage());
		}

		return response;
	}

	/**
	 * 生成条码生成文件
	 * 
	 * @param selectedBarcodes
	 * @param templatePosition
	 * @return
	 */
	@Transactional
	public Map<String, Object> generateBarcodeFile(String barcodes, String templatePath) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		Set<String> selectedBarcodes = new HashSet<String>();
		String[] bs = barcodes.split(",");
		if (bs.length > 0) {
			for (int i = 0; i < bs.length; i++) {
				selectedBarcodes.add(bs[i]);
			}
		}

		ByteArrayInputStream byteArrayInputStream;
		try {
			HSSFWorkbook wb = null;

			// to get the order information from database
			List<ProductBarcode> products = new ArrayList<ProductBarcode>();

			if (selectedBarcodes != null && selectedBarcodes.size() > 0) {
				DetachedCriteria productCriteria = DetachedCriteria.forClass(ProductBarcode.class, "p");
				productCriteria.add(Restrictions.in("p.barcode", selectedBarcodes));

				products = productBarcodeDaoImpl.getByCritera(productCriteria, true);
			}
			BarcodeCreationTemplate barcodeTemplate = new BarcodeCreationTemplate(products, templatePath);

			wb = barcodeTemplate.process();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			try {
				wb.write(os);
			} catch (IOException e) {
				e.printStackTrace();
			}
			byte[] content = os.toByteArray();
			byteArrayInputStream = new ByteArrayInputStream(content);
			returnMap.put("stream", byteArrayInputStream);

			return returnMap;
		} catch (Exception ex) {
			loggerLocal.error(ex);
		}
		return null;
	}
	
	/**
	 * 吊牌打印
	 * 
	 * @param selectedBarcodes
	 * @param templatePosition
	 * @return
	 */
	@Transactional
	public Map<String, Object> generateTagPrintFile(String barcodes, String templatePath) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		Set<String> selectedBarcodes = new HashSet<String>();
		
		String[] bs = barcodes.split(",");
		if (bs.length > 0) {
			for (int i = 0; i < bs.length; i++) {
				selectedBarcodes.add(bs[i]);
			}
		}

		ByteArrayInputStream byteArrayInputStream;
		try {
			HSSFWorkbook wb = null;

			List<ProductBarcode> products = new ArrayList<ProductBarcode>();
			List<TagPrintVO> vos = new ArrayList<TagPrintVO>();

			if (selectedBarcodes != null && selectedBarcodes.size() > 0) {
				DetachedCriteria productCriteria = DetachedCriteria.forClass(ProductBarcode.class, "p");
				productCriteria.add(Restrictions.in("p.barcode", selectedBarcodes));

				products = productBarcodeDaoImpl.getByCritera(productCriteria, true);
			}
			
			if (products.size() !=0) {
				for (ProductBarcode productBarcode : products) {
					//1.正常码
					Product product = productBarcode.getProduct();
					
					if ((product.getSizeMax()-product.getSizeMin())%10 ==0) {
						int nums = (product.getSizeMax()-product.getSizeMin())/10;
						int sizeMin = product.getSizeMin();
						for (int i = 0; i < nums+1; i++) {
							TagPrintVO vo = new TagPrintVO(productBarcode,sizeMin);
							vos.add(vo);
							sizeMin+=10;
						}
					}else { //2.半码数
						int nums = (product.getSizeMax()-product.getSizeMin())/5;
						int sizeMin = product.getSizeMin();
						for (int i = 0; i < nums+1; i++) {
							TagPrintVO vo = new TagPrintVO(productBarcode,sizeMin);
							vos.add(vo);
							sizeMin+=5;
						}
					}					
				}
			}

			TagPrintTemplate tagPrintTemplate = new TagPrintTemplate(vos,templatePath);

			wb = tagPrintTemplate.process();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			try {
				wb.write(os);
			} catch (IOException e) {
				e.printStackTrace();
			}
			byte[] content = os.toByteArray();
			byteArrayInputStream = new ByteArrayInputStream(content);
			returnMap.put("stream", byteArrayInputStream);

			return returnMap;
		} catch (Exception ex) {
			loggerLocal.error(ex);
		}
		return null;
	}

	
	/**
	 * 构建查询条件
	 * @param productBarcode
	 * @param brandIds
	 * @return
	 */
	private DetachedCriteria buildProductBarcodeCriteriaTwo(ProductBarcode productBarcode, List<Integer> brandIds) {
		DetachedCriteria productBarcodeCriteria = DetachedCriteria.forClass(ProductBarcode.class);
		DetachedCriteria productCriteria = productBarcodeCriteria.createCriteria("product");

		if (productBarcode.getChainStore() != null && productBarcode.getChainStore().getChain_id() == 99)
			productBarcodeCriteria.add(Restrictions.isNull("chainStore"));
		else if (productBarcode.getChainStore() != null && productBarcode.getChainStore().getChain_id() == 0)
			productBarcodeCriteria.add(Restrictions.isNotNull("chainStore"));

		if (!productBarcode.getProduct().getProductCode().trim().equals(""))
			productCriteria.add(Restrictions.like("productCode", productBarcode.getProduct().getProductCode().trim(), MatchMode.ANYWHERE));

		if (!productBarcode.getProduct().getFactoryCode().trim().equals(""))
			productCriteria.add(Restrictions.like("factoryCode", productBarcode.getProduct().getFactoryCode().trim(), MatchMode.ANYWHERE));

		
		if (!productBarcode.getBarcode().trim().equals(""))
			productBarcodeCriteria.add(Restrictions.eq("barcode", productBarcode.getBarcode()));

		if (productBarcode.getProduct().getArea().getArea_ID() != 0)
			productCriteria.add(Restrictions.eq("area.area_ID", productBarcode.getProduct().getArea().getArea_ID()));
		if (productBarcode.getProduct().getYear().getYear_ID() != 0)
			productCriteria.add(Restrictions.eq("year.year_ID", productBarcode.getProduct().getYear().getYear_ID()));
		if (productBarcode.getProduct().getQuarter().getQuarter_ID() != 0)
			productCriteria.add(
					Restrictions.eq("quarter.quarter_ID", productBarcode.getProduct().getQuarter().getQuarter_ID()));
		if (brandIds != null && brandIds.size() != 0) {
			if (brandIds.size() == 1)
				productCriteria.add(Restrictions.eq("brand.brand_ID", brandIds.get(0)));
			else
				productCriteria.add(Restrictions.in("brand.brand_ID", brandIds));
		}
		
		if (productBarcode.getProduct().getCategoryLevel1().getCategory_ID() != 0)
			productCriteria.add(Restrictions.eq("categoryLevel1.category_ID",
					productBarcode.getProduct().getCategoryLevel1().getCategory_ID()));

		if (productBarcode.getProduct().getCategory().getCategory_ID() != 0)
			productCriteria.add(Restrictions.eq("category.category_ID",
					productBarcode.getProduct().getCategory().getCategory_ID()));

		Set<Integer> statusSet = new HashSet<Integer>();
		statusSet.add(ProductBarcode.STATUS_OK);
		statusSet.add(ProductBarcode.STATUS_NOT_PRODUCE);
	    
		productBarcodeCriteria.add(Restrictions.in("status", statusSet));
		productBarcodeCriteria.addOrder(Order.desc("createDate"));

		return productBarcodeCriteria;
	}

	
	/**
	 * 根据条件查询图片信息
	 * @param formBean
	 * @param page
	 * @param rowPerPage
	 * @return
	 */
	public Map getBarcodesFromCriteriaTwo(ProductActionFormBean formBean,int page, int rowPerPage) {
		Map data = new HashMap<String, Object>();
		List<Integer> brandIds = Common_util.string2IntList(formBean.getBrandIds());
		
		List<ProductDetailsVO> productVOS = new ArrayList<ProductDetailsVO>();

		List<ProductBarcode> barcodes = new ArrayList<ProductBarcode>();

		DetachedCriteria searchCritiera = buildProductBarcodeCriteriaTwo(formBean.getProductBarcode(), brandIds);
		int startRow = Common_util.getFirstRecord(page, rowPerPage);
		barcodes = productBarcodeDaoImpl.getByCritera(searchCritiera, startRow, rowPerPage, false);

		DetachedCriteria rowTotalCritiera = buildProductBarcodeCriteriaTwo(formBean.getProductBarcode(), brandIds);
		rowTotalCritiera.setProjection(Projections.rowCount());
		int totalRecord = Common_util.getProjectionSingleValue(productBarcodeDaoImpl.getByCriteriaProjection(rowTotalCritiera, false));

		if (barcodes != null) {
			for (ProductBarcode product : barcodes) {
					if (product.getProduct().getBrand().getBelong_To() == formBean.getHeadBrand()) {
						ProductDetailsVO detailsVO = new ProductDetailsVO();
						detailsVO.setBarcode(product.getBarcode());
						detailsVO.setBrand(product.getProduct().getBrand().getBrand_Name());
						detailsVO.setCategoryLevel1(product.getProduct().getCategoryLevel1().getCategory_Name());
						detailsVO.setCategory(product.getProduct().getCategory().getCategory_Name());
						if (product.getColor() != null) {
							detailsVO.setColor(product.getColor().getName());
						} else {
							detailsVO.setColor(null);
						}
						detailsVO.setFactoryCode(product.getProduct().getFactoryCode());
						detailsVO.setProductCode(product.getProduct().getProductCode());
						detailsVO.setYear(product.getProduct().getYear().getYear());
						detailsVO.setQuarter(product.getProduct().getQuarter().getQuarter_Name());
						detailsVO.setSalesPrice(product.getProduct().getSalesPrice());
						detailsVO.setImg(productBarcodePicDaoImpl.getURLPicsPathByBarcode(product.getBarcode(),ProductBarcodePic.TYPE_PING_MIAN_PIC));
						detailsVO.setInventory(headQInventoryStockDAOImpl.getInventory(product.getId()));
						productVOS.add(detailsVO);					
				}
			}
		}

		data.put("rows", productVOS);
		data.put("total", totalRecord);
		return data;

	}
	

	/**
	 * 文件上传
	 * @param inventory
	 * @param inventoryFileName
	 * @param inventoryContentType
	 * @return
	 * @throws IOException 
	 */
	public Response uplodFile(File imageFile, String fileName,String comment,UserInfor loginUserInfor) throws IOException {
		Response response = new Response();
		//文件名称是否纯字母：汉字会导致下载文件名称不对
		String name = fileName.substring(0,fileName.indexOf("."));
		if (StrCheckUtils.isContainSpecialCharacter(name)) {
			response.setMessage("文件名称不合法,文件名不能包含特殊符号（包含空格）");
			return response;
		}
		if (imageFile.length() == 0) {
			response.setMessage("上传失败，文件过小，文件大小为0kb");
			return response;
		}
		if (imageFile.length()>FileUtils.fileMaxSize) {
			response.setMessage("上传失败，文件过大（文件大小不能超过20M) ");
			return response;
		}
		if (imageFile != null) {
						
			SystemFile sFile = systemFileDaoImpl.selectFileByName(fileName);
			if (sFile != null) {
				response.setMessage("该文件已存在");
			}else {
				String dirctory = SystemParm.getParm("QX_SYSTEM_FILE");
				File file = new File(dirctory);
				if (file.exists() == false) {
					file.mkdirs();
				}
				String fileSavePath = dirctory + "/" + fileName;
				File destFile =new File(fileSavePath);

				destFile.createNewFile();
												
				try (FileInputStream fis = new FileInputStream(imageFile);  
			             FileOutputStream fos = new FileOutputStream(destFile)) {  			  
			            byte[] buffer = new byte[1024];  
			            int length;  
			            // 从源文件中读取数据  
			            while ((length = fis.read(buffer)) > 0) {  
			                // 写入到目标文件中  
			                fos.write(buffer, 0, length);  
			            }  			              
			            System.out.println("文件复制成功:"+fileName);  
			        } catch (IOException e) {  
			            e.printStackTrace();  
			            System.out.println("文件复制失败: " + e.getMessage());  
			            response.setMessage("文件复制失败");
			        } 
				SystemFile systemFile = new SystemFile();
				systemFile.setFileName(fileName);
				systemFile.setComment(comment);
				systemFile.setCreateBy(loginUserInfor.getUser_name());
				systemFile.setCreateTime(Common_util.getToday());
				systemFile.setFilePath(dirctory+"/"+fileName);
				systemFile.setFileSize(FileUtils.FormetFileSize(imageFile.length()));
				systemFileDaoImpl.save(systemFile, true);
				response.setMessage("文件上传成功");
			}
			
		}else {
			response.setMessage("上传文件为空");
		}	
		return response;
	}

	
	/**
	 *
	 * @param content  内容
	 * @param filePath 文件路径
	 * @return
	 */
	public static void writeReport(int categoryId,int categoryLevelId,int productId, String filePath) {
		BufferedWriter out = null;
		try {
			File file = new File(filePath);
			if (!file.exists()) {
				file.getParentFile().mkdirs();
				file.createNewFile();
			}
			// 编码格式可自己更换
			out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8"));
			out.write("UPDATE product SET category_ID = "+categoryId+", category_level_1 = "+categoryLevelId+" WHERE product_ID = "+productId+";" + "\r\n");

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				out.close();

			} catch (IOException e) {
				e.printStackTrace();

			}
		}
	}

	/**
	 * 筛选该货号已经存在的颜色
	 * 
	 * @param productCode
	 * @return
	 */
	public List<Color> getExcludeColors(int productId, Color color) {
		List<Color> colorIds = new ArrayList<Color>();
		List<Color> colors = new ArrayList<Color>();
		if (color == null) {
			colors = colorDaoImpl.getAll(true);
		} else {
			// 1.拿到当前货号在使用的所有颜色

			List<ProductBarcode> productBarcodes = productBarcodeDaoImpl.selectBarcodeByInIds(productId);

			if (productBarcodes.size() != 0) {
				for (ProductBarcode barcode : productBarcodes) {
					if (barcode.getColor() != null)
					    colorIds.add(barcode.getColor());
				}
			}

			// 2.排除当前要修改的货品的颜色
			Iterator<Color> iterator = colorIds.iterator();
			while (iterator.hasNext()) {
				if (iterator.next().getColorId() == color.getColorId()) {
					iterator.remove();
				}

			}
			colors = colorDaoImpl.selectByColors(colorIds);
		}

		return colors;
	}

	/**
	 * 根据查询条件货品分页信息
	 * @param formBean
	 * @param page
	 * @param rows
	 * @param sort
	 * @param order
	 * @return
	 */
	public Response selectParoductByPage(ProductActionFormBean formBean, int page, int rows, String sort,
			String order) {
		Response response = new Response();
		Map dataMap = new HashMap();

		//获取总条数的 criteria
		int total = 0;
		DetachedCriteria productBarcodeTotalCriteria = DetachedCriteria.forClass(ProductBarcode.class);
		DetachedCriteria productTotalCriteria = productBarcodeTotalCriteria.createAlias("product","product");
		//获取list的 criteria
		List<ProductBarcode> products = new ArrayList<ProductBarcode>();
		DetachedCriteria productBarcodeCriteria = DetachedCriteria.forClass(ProductBarcode.class);
		DetachedCriteria productCriteria = productBarcodeCriteria.createAlias("product","product");

		//1. 获取总条数
		if (formBean.getBarcode() != null && !formBean.getBarcode().equals("")) {
			productBarcodeTotalCriteria.add(Restrictions.eq("barcode", formBean.getBarcode()));
		}
		if (formBean.getProductCode() != null && !formBean.getProductCode().equals("")) {
			productTotalCriteria.add(Restrictions.like("product.productCode", formBean.getProductCode(),MatchMode.ANYWHERE));
		}
		if (!formBean.getBarcode().equals("") || !formBean.getProductCode().equals("")) {
			productTotalCriteria.setProjection(Projections.rowCount());
			total =  Common_util.getProjectionSingleValue(productBarcodeDaoImpl.getByCriteriaProjection(productTotalCriteria, true));
		}
						
		//2. 获取当页数据
		productBarcodeCriteria.addOrder(Order.desc("id"));		
		if (formBean.getBarcode() != null && !formBean.getBarcode().equals("")) {
			productBarcodeCriteria.add(Restrictions.eq("barcode", formBean.getBarcode()));
		}
		if (formBean.getProductCode() != null && !formBean.getProductCode().equals("")) {
			productCriteria.add(Restrictions.like("product.productCode", formBean.getProductCode(),MatchMode.ANYWHERE));
		}
		if (!formBean.getBarcode().equals("") || !formBean.getProductCode().equals("")) {
			products = productBarcodeDaoImpl.getByCritera(productCriteria, Common_util.getFirstRecord(page, rows),rows, true);
			total =  Common_util.getProjectionSingleValue(productBarcodeDaoImpl.getByCriteriaProjection(productTotalCriteria, true));
		}
		
		List<ProductBarcodeVO> vos = new ArrayList<ProductBarcodeVO>();
		if (products.size() !=0) {
			for (ProductBarcode barcode : products) {
				ProductBarcodeVO vo = new ProductBarcodeVO(barcode,true);
				vos.add(vo);
			}
		}						
		dataMap.put("rows", vos);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	/**
	 * 查询公司所有品牌
	 * @return
	 */
	public Response listBrandsData(String brand,Integer page, Integer rowPerPage, String sort, String sortOrder) {
		Response response = new Response();
		@SuppressWarnings("rawtypes")
		Map dataMap = new HashMap();
		
		//获取总条数的 criteria
		DetachedCriteria brandTotalCriteria = DetachedCriteria.forClass(Brand.class);
		//获取list的 criteria
		DetachedCriteria brandCriteria = DetachedCriteria.forClass(Brand.class);
		if (StringUtils.isNotEmpty(brand)){
			String brandName = StringUtils.trim(brand);
			if(StrCheckUtils.isLetter(brandName)) {
				brandTotalCriteria.add(Restrictions.or(Restrictions.like("pinyin", brandName, MatchMode.ANYWHERE), Restrictions.like("comment", brandName, MatchMode.ANYWHERE)));
				brandCriteria.add(Restrictions.or(Restrictions.like("pinyin", brandName, MatchMode.ANYWHERE), Restrictions.like("comment", brandName, MatchMode.ANYWHERE)));
			}else {
				brandTotalCriteria.add(Restrictions.or(Restrictions.like("brand_Name", brandName, MatchMode.ANYWHERE), Restrictions.like("comment", brandName, MatchMode.ANYWHERE)));
				brandCriteria.add(Restrictions.or(Restrictions.like("brand_Name", brandName, MatchMode.ANYWHERE), Restrictions.like("comment", brandName, MatchMode.ANYWHERE)));
			}			
		}

		//1. 获取总条数
		brandTotalCriteria.setProjection(Projections.rowCount());
		int total = Common_util.getProjectionSingleValue(brandDaoImpl.getByCriteriaProjection(brandTotalCriteria, true));
		
		//2. 获取当页数据
		brandCriteria.add(Restrictions.isNull("chainStore"));
		brandCriteria.addOrder(Order.desc("brand_ID"));
		List<Brand> custs = brandDaoImpl.getByCritera(brandCriteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);
		List<BrandVO> brandVOs = new ArrayList<BrandVO>();
		if (custs.size() !=0) {
			for (Brand brand2 : custs) {
				BrandVO brandVO = new BrandVO(brand2);
				brandVOs.add(brandVO);			
			}
		}		
		dataMap.put("rows", brandVOs);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	/**
	 * 根据品牌id集合查询
	 * @param brandIds
	 * @return
	 */
	public Response listBrandsData(String brandIds) {
		Response response = new Response();
		@SuppressWarnings("rawtypes")
		Map dataMap = new HashMap();
		if (brandIds.length() !=0) {
			DetachedCriteria brandCriteria = DetachedCriteria.forClass(Brand.class);

			brandCriteria.add(Restrictions.isNull("chainStore"));
			String[] brands = brandIds.split(",");
			List<Integer> bs = new ArrayList<Integer>();
			for (int i = 0; i < brands.length; i++) {
				bs.add(Integer.valueOf(brands[i]));
			}
			brandCriteria.add(Restrictions.in("brand_ID", bs));
			List<Brand> custs = brandDaoImpl.getByCritera(brandCriteria,true);
			List<BrandVO> brandVOs = new ArrayList<BrandVO>();
			if (custs.size() !=0) {
				for (Brand brand2 : custs) {
					BrandVO brandVO = new BrandVO(brand2);
					brandVOs.add(brandVO);			
				}
			}	
			dataMap.put("rows", brandVOs);		
		}else {
			dataMap.put("rows", null);
		}
		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	public Response listProductsData(String productCode, Integer page, Integer rowPerPage, String sort, String sortOrder) {
		Response response = new Response();
		Map dataMap = new HashMap();
		
		//获取总条数的 criteria
		DetachedCriteria totalCriteria = DetachedCriteria.forClass(ProductBarcode.class);
		DetachedCriteria totalProductCriteria = totalCriteria.createCriteria("product");
		//获取list的 criteria
		DetachedCriteria criteria = DetachedCriteria.forClass(ProductBarcode.class);
		DetachedCriteria productCriteria = criteria.createCriteria("product");
		if (StringUtils.isNotBlank(productCode)){
				criteria.add(Restrictions.isNull("chainStore"));
				if (productCode.matches(Common_util.BARCODE_REGEX)) {
					criteria.add(Restrictions.eq("barcode", productCode));
					totalCriteria.add(Restrictions.eq("barcode", productCode));
				} else {
				    productCriteria.add(Restrictions.like("productCode", productCode, MatchMode.ANYWHERE));
				    totalProductCriteria.add(Restrictions.like("productCode", productCode, MatchMode.ANYWHERE));
				}
			
				Set<Integer> statusSet = new HashSet<Integer>();
				statusSet.add(ProductBarcode.STATUS_OK);
				statusSet.add(ProductBarcode.STATUS_NOT_PRODUCE);
	
				criteria.add(Restrictions.in("status", statusSet));
				productCriteria.addOrder(Order.desc("year.year_ID"));
				productCriteria.addOrder(Order.desc("quarter.quarter_ID"));
				criteria.addOrder(Order.desc("createDate"));
				criteria.add(Restrictions.isNull("chainStore"));

				totalCriteria.add(Restrictions.isNull("chainStore"));				
				totalCriteria.add(Restrictions.eq("status", ProductBarcode.STATUS_OK));
				totalCriteria.addOrder(Order.desc("createDate"));
							
		}else {
			criteria.add(Restrictions.isNull("chainStore"));
			criteria.add(Restrictions.eq("status", ProductBarcode.STATUS_OK));
			productCriteria.addOrder(Order.desc("year.year_ID"));
			productCriteria.addOrder(Order.desc("quarter.quarter_ID"));
			criteria.addOrder(Order.desc("createDate"));
			
			//条数
			totalCriteria.add(Restrictions.isNull("chainStore"));
			totalCriteria.add(Restrictions.eq("status", ProductBarcode.STATUS_OK));
			totalCriteria.addOrder(Order.desc("createDate"));
		}
		//1. 获取总条数
		totalCriteria.setProjection(Projections.rowCount());
		int total = Common_util.getProjectionSingleValue(productBarcodeDaoImpl.getByCriteriaProjection(totalCriteria, true));
		
		//2. 获取当页数据

		List<ProductBarcode> pList = productBarcodeDaoImpl.getByCritera(criteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);
		List<ProductBarcodeVO> pbVos = new ArrayList<ProductBarcodeVO>();
		if (pList.size() !=0) {
			for (ProductBarcode pb : pList) {
				ProductBarcodeVO vo = new ProductBarcodeVO(pb);
				pbVos.add(vo);			
			}
		}		
		dataMap.put("rows", pbVos);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	public Response listpbsData(String pbIds) {
		Response response = new Response();
		@SuppressWarnings("rawtypes")
		Map dataMap = new HashMap();
		if (pbIds.length() !=0) {
			DetachedCriteria criteria = DetachedCriteria.forClass(ProductBarcode.class);
			DetachedCriteria productCriteria = criteria.createCriteria("product");

			
			String[] ps = pbIds.split(",");
			List<Integer> ids = new ArrayList<Integer>();
			for (int i = 0; i < ps.length; i++) {
				ids.add(Integer.valueOf(ps[i]));
			}
			
			criteria.add(Restrictions.isNull("chainStore"));
			criteria.add(Restrictions.in("id", ids));
			
			Set<Integer> statusSet = new HashSet<Integer>();
			statusSet.add(ProductBarcode.STATUS_OK);
			statusSet.add(ProductBarcode.STATUS_NOT_PRODUCE);

			criteria.add(Restrictions.in("status", statusSet));
			productCriteria.addOrder(Order.desc("year.year_ID"));
			productCriteria.addOrder(Order.desc("quarter.quarter_ID"));
			productCriteria.addOrder(Order.desc("brand.brand_ID"));
			productCriteria.addOrder(Order.desc("productCode"));	
			
			List<ProductBarcode> pList = productBarcodeDaoImpl.getByCritera(criteria,true);
			List<ProductBarcodeVO> pbVos = new ArrayList<ProductBarcodeVO>();
			if (pList.size() !=0) {
				for (ProductBarcode pb : pList) {
					ProductBarcodeVO vo = new ProductBarcodeVO(pb);
					pbVos.add(vo);			
				}
			}	
			dataMap.put("rows", pbVos);		
		}else {
			dataMap.put("rows", null);
		}
		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

		/**
	 * 查询公司所有颜色
	 * @return
	 */
	public Response listColorsData(String color,Integer page, Integer rowPerPage, String sort, String sortOrder) {
		Response response = new Response();
		@SuppressWarnings("rawtypes")
		Map dataMap = new HashMap();
		
		//获取总条数的 criteria
		DetachedCriteria colorTotalCriteria = DetachedCriteria.forClass(Color.class);
		//获取list的 criteria
		DetachedCriteria colorCriteria = DetachedCriteria.forClass(Color.class);
		if (StringUtils.isNotEmpty(color)){
			String colorCode = StringUtils.trim(color);
			if(StrCheckUtils.isLetter(colorCode)) { //英文
				colorTotalCriteria.add(Restrictions.like("code", colorCode, MatchMode.ANYWHERE));
				colorCriteria.add(Restrictions.like("code", colorCode, MatchMode.ANYWHERE));
			}else {
				
				List<String> list  = Arrays.asList(color.split("-"));
				
				Criterion criterion = null;
				if (list.size() >1) {
					criterion = Restrictions.or(Restrictions.like("name", list.get(0), MatchMode.ANYWHERE), Restrictions.like("name", list.get(1), MatchMode.ANYWHERE));//第一个查询条件
					for(int i = 2; i < list.size(); i++){
					   criterion = Restrictions.or(criterion, Restrictions.like("name", list.get(i), MatchMode.ANYWHERE));//第N+个查询条件
					}
				} else 
					criterion = Restrictions.like("name",color, MatchMode.ANYWHERE);
									
				colorTotalCriteria.add(criterion);
				colorCriteria.add(criterion);
			}			
		}

		//1. 获取总条数
		colorTotalCriteria.setProjection(Projections.rowCount());
		int total = Common_util.getProjectionSingleValue(colorDaoImpl.getByCriteriaProjection(colorTotalCriteria, true));
		
		//2. 获取当页数据		
		List<Color> colors = colorDaoImpl.getByCritera(colorCriteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);
		
		dataMap.put("rows", colors);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

		public Response listColorsData(String colors) {
			Response response = new Response();
			@SuppressWarnings("rawtypes")
			Map dataMap = new HashMap();
			if (colors.length() !=0) {
				DetachedCriteria colorCriteria = DetachedCriteria.forClass(Color.class);

				String[] cs = colors.split(",");
				List<Integer> colos = new ArrayList<Integer>();
				for (int i = 0; i < cs.length; i++) {
					colos.add(Integer.valueOf(cs[i]));
				}
				colorCriteria.add(Restrictions.in("colorId", colos));
				List<Color> sList = colorDaoImpl.getByCritera(colorCriteria,true);

				dataMap.put("rows", sList);		
			}else {
				dataMap.put("rows", null);
			}
			response.setReturnValue(dataMap);
			response.setReturnCode(Response.SUCCESS);
			return response;
		}
	
		
		
		public static void main(String[] args) {
			String color = "红-白-黑";
			List<String> list  = Arrays.asList(color.split("-"));
			for (String co : list) {
				System.out.println(co);
			}
		}

	/**
	 * 系统文件下载
	 * @param fileName
	 * @return
	 */
	public InputStream downloadFile(String fileName) {
		String filePath = SystemParm.getParm("QX_SYSTEM_FILE") + "/" + fileName;
		
		File file = new File(filePath);
		InputStream inputStream = null;
		if (file.exists()) {
			try {
				inputStream = new FileInputStream(file);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return inputStream;
	}

	
	/**
	 * 获取总部客户信息
	 * @param custName
	 * @param page
	 * @param rows
	 * @param sort
	 * @param order
	 * @return
	 */
	public Response listCustsData(String custName, int page, int rows, String sort, String order) {
		Response response = new Response();
		Map dataMap = new HashMap();
		
		//获取总条数的 criteria
		DetachedCriteria totalCriteria = DetachedCriteria.forClass(HeadQCust.class);
		//获取list的 criteria
		DetachedCriteria criteria = DetachedCriteria.forClass(HeadQCust.class);
		if (StringUtils.isNotBlank(custName)){
			Pattern pattern = Pattern.compile("[A-Za-z]*");
			Matcher isNum = pattern.matcher(custName);
			if (isNum.matches()) {
				criteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
				totalCriteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
			}else {
				criteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
				totalCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}							
		}
		
		criteria.add(Restrictions.eq("status", HeadQCust.CustStatusEnum.GOOD.getKey()));
		totalCriteria.add(Restrictions.eq("status", HeadQCust.CustStatusEnum.GOOD.getKey()));
		
		//1. 获取总条数
		totalCriteria.setProjection(Projections.rowCount());
		int total = Common_util.getProjectionSingleValue(headQCustDaoImpl.getByCriteriaProjection(totalCriteria, true));
		
		//2. 获取当页数据
		List<HeadQCust> custs = headQCustDaoImpl.getByCritera(criteria, Common_util.getFirstRecord(page, rows), rows, true);
	
		dataMap.put("rows", custs);
		dataMap.put("total", total);

		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	public Response selectBarcodeInfo(String barcode) {
		Response response = new Response();
		@SuppressWarnings("rawtypes")
		Map dataMap = new HashMap();
		if (StringUtils.isNotBlank(barcode)) {

			ProductBarcode pBarcode = productBarcodeDaoImpl.getByBarcode(barcode);
			if (pBarcode.getProduct().getUnit() !=null) {
				ProductUnit productUnit = productUnitDaoImpl.getUnitByName(pBarcode.getProduct().getUnit());
				pBarcode.getProduct().setProductUnit(productUnit);
			}
			if (pBarcode.getProduct().getNumPerHand() != Common_util.ALL_RECORD_NEW) {
				NumPerHand perHand = numPerHandDaoImpl.getNumPerHand(pBarcode.getProduct().getNumPerHand());
				pBarcode.getProduct().setnPerHand(perHand);
			}

			dataMap.put("rows", pBarcode);		
		}else {
			dataMap.put("rows", null);
		}
		response.setReturnValue(dataMap);
		response.setReturnCode(Response.SUCCESS);
		return response;
	}

	/**
	 * 导出产品信息 ->条件导出
	 * @param productBarcode
	 * @param brandIds
	 * @param belongTo2
	 * @param startDate
	 * @param endDate
	 * @param createDate
	 * @param page
	 * @param rowPerPage
	 * @param sort
	 * @param order
	 * @param templatePath
	 * @return
	 */
	public Map<String, Object> generateExcelReportByCondition(ProductBarcode productBarcode, String brandIds,
			int belongTo2, java.sql.Date startDate, java.sql.Date endDate, String createDate, int page, int rowPerPage,
			String sort, String order, String templatePath) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		DetachedCriteria productBarcodeCriteria = buildProductBarcodeCritera(productBarcode,brandIds,belongTo2,startDate,endDate,createDate,page,rowPerPage,sort,order);

		
		ByteArrayInputStream byteArrayInputStream;
		try {
			HSSFWorkbook wb = null;
			List<ProductBarcode> barcodes = productBarcodeDaoImpl.getByCritera(productBarcodeCriteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);			

			BarcodeTemplate barcodeTemplate = new BarcodeTemplate(barcodes, templatePath);

			wb = barcodeTemplate.process();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			try {
				wb.write(os);
			} catch (IOException e) {
				e.printStackTrace();
			}
			byte[] content = os.toByteArray();
			byteArrayInputStream = new ByteArrayInputStream(content);
			returnMap.put("stream", byteArrayInputStream);

			return returnMap;
		} catch (Exception ex) {
			loggerLocal.error(ex);
		}
		return null;
	}
	
	
	/**
	 * 导出条码打印->条件打印
	 * @param productBarcode
	 * @param brandIds
	 * @param belongTo2
	 * @param startDate
	 * @param endDate
	 * @param createDate
	 * @param page
	 * @param rowPerPage
	 * @param sort
	 * @param orderBy
	 * @param templatePath
	 * @return
	 */
	public Map<String, Object> exportToPrintBarcodeAll(ProductBarcode productBarcode, String brandIds,
			int belongTo2, java.sql.Date startDate, java.sql.Date endDate, String createDate, int page, int rowPerPage,
			String sort, String orderBy, String templatePath) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		DetachedCriteria productBarcodeCriteria = buildProductBarcodeCritera(productBarcode,brandIds,belongTo2,startDate,endDate,createDate,page,rowPerPage,sort,orderBy);

		
		ByteArrayInputStream byteArrayInputStream;
		try {
			HSSFWorkbook wb = null;
			List<ProductBarcode> barcodes = productBarcodeDaoImpl.getByCritera(productBarcodeCriteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);			
			InventoryOrder order = new InventoryOrder();
			Set<InventoryOrderProduct> inventoryOrderProducts = order.getProduct_Set();
			for (ProductBarcode product : barcodes) {
				InventoryOrderProduct orderProduct = new InventoryOrderProduct();
				orderProduct.setProductBarcode(product);
				inventoryOrderProducts.add(orderProduct);
			}
			JinSuanOrderTemplate orderTemplate = new JinSuanOrderTemplate(order, templatePath);
			wb = orderTemplate.process();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			try {
				wb.write(os);
			} catch (IOException e) {
				e.printStackTrace();
			}
			byte[] content = os.toByteArray();
			byteArrayInputStream = new ByteArrayInputStream(content);
			returnMap.put("stream", byteArrayInputStream);

			return returnMap;
		} catch (Exception ex) {
			loggerLocal.error(ex);
		}
		return null;
	}

	/**
	 * 导出条码给其他系统再生成 ->条件导出
	 * @param productBarcode
	 * @param brandIds
	 * @param belongTo2
	 * @param startDate
	 * @param endDate
	 * @param createDate
	 * @param page
	 * @param rowPerPage
	 * @param sort
	 * @param orderBy
	 * @param templatePath
	 * @return
	 */
	public Map<String, Object> generateBarcodeFileAll(ProductBarcode productBarcode, String brandIds, int belongTo2,
			java.sql.Date startDate, java.sql.Date endDate, String createDate, int page, int rowPerPage, String sort,
			String orderBy, String templatePath) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		DetachedCriteria productBarcodeCriteria = buildProductBarcodeCritera(productBarcode,brandIds,belongTo2,startDate,endDate,createDate,page,rowPerPage,sort,orderBy);
		ByteArrayInputStream byteArrayInputStream;
		try {
			HSSFWorkbook wb = null;

			List<ProductBarcode> products = productBarcodeDaoImpl.getByCritera(productBarcodeCriteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);	
			BarcodeCreationTemplate barcodeTemplate = new BarcodeCreationTemplate(products, templatePath);

			wb = barcodeTemplate.process();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			try {
				wb.write(os);
			} catch (IOException e) {
				e.printStackTrace();
			}
			byte[] content = os.toByteArray();
			byteArrayInputStream = new ByteArrayInputStream(content);
			returnMap.put("stream", byteArrayInputStream);

			return returnMap;
		} catch (Exception ex) {
			loggerLocal.error(ex);
		}
		return null;
	}

	/**
	 * 吊牌打印 ->条件打印
	 * @param barcode
	 * @param brandIds
	 * @param belongTo2
	 * @param startDate
	 * @param endDate
	 * @param createDate
	 * @param page
	 * @param rowPerPage
	 * @param sort
	 * @param orderBy
	 * @param templatePath
	 * @return
	 */
	public Map<String, Object> generateTagPrintFileAll(ProductBarcode barcode, String brandIds, int belongTo2,
			java.sql.Date startDate, java.sql.Date endDate, String createDate, int page, int rowPerPage, String sort,
			String orderBy, String templatePath) {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		DetachedCriteria productBarcodeCriteria = buildProductBarcodeCritera(barcode,brandIds,belongTo2,startDate,endDate,createDate,page,rowPerPage,sort,orderBy);
		ByteArrayInputStream byteArrayInputStream;
		try {
			HSSFWorkbook wb = null;
			List<ProductBarcode> products = productBarcodeDaoImpl.getByCritera(productBarcodeCriteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);	
			List<TagPrintVO> vos = new ArrayList<TagPrintVO>();
			
			if (products.size() !=0) {
				for (ProductBarcode productBarcode : products) {
					//1.正常码
					Product product = productBarcode.getProduct();
					
					if ((product.getSizeMax()-product.getSizeMin())%10 ==0) {
						int nums = (product.getSizeMax()-product.getSizeMin())/10;
						int sizeMin = product.getSizeMin();
						for (int i = 0; i < nums+1; i++) {
							TagPrintVO vo = new TagPrintVO(productBarcode,sizeMin);
							vos.add(vo);
							sizeMin+=10;
						}
					}else { //2.半码数
						int nums = (product.getSizeMax()-product.getSizeMin())/5;
						int sizeMin = product.getSizeMin();
						for (int i = 0; i < nums+1; i++) {
							TagPrintVO vo = new TagPrintVO(productBarcode,sizeMin);
							vos.add(vo);
							sizeMin+=5;
						}
					}					
				}
			}

			TagPrintTemplate tagPrintTemplate = new TagPrintTemplate(vos,templatePath);

			wb = tagPrintTemplate.process();

			ByteArrayOutputStream os = new ByteArrayOutputStream();
			try {
				wb.write(os);
			} catch (IOException e) {
				e.printStackTrace();
			}
			byte[] content = os.toByteArray();
			byteArrayInputStream = new ByteArrayInputStream(content);
			returnMap.put("stream", byteArrayInputStream);

			return returnMap;
		} catch (Exception ex) {
			loggerLocal.error(ex);
		}
		return null;
	}

	/**
	 * 条件同步价格
	 * @param productBarcode
	 * @param brandIds
	 * @param belongTo2
	 * @param startDate
	 * @param endDate
	 * @param createDate
	 * @param page
	 * @param rowPerPage
	 * @param sort
	 * @param orderBy
	 * @param loginUserInfor
	 * @return
	 */
	public Map<String, String> synchronizePriceAll(ProductBarcode productBarcode, String brandIds, int belongTo2,
			java.sql.Date startDate, java.sql.Date endDate, String createDate, int page, int rowPerPage, String sort,
			String orderBy, UserInfor loginUserInfor) {
		DetachedCriteria productBarcodeCriteria = buildProductBarcodeCritera(productBarcode,brandIds,belongTo2,startDate,endDate,createDate,page,rowPerPage,sort,orderBy);
		List<ProductBarcode> products = productBarcodeDaoImpl.getByCritera(productBarcodeCriteria, Common_util.getFirstRecord(page, rowPerPage), rowPerPage, true);	

		Map<String, String> msgMap = this.synchronizePrice(null,products, loginUserInfor);
		
		return msgMap;
	}

	/**
	 * 修改条码的状态
	 * @param id
	 * @param status
	 * @return
	 */
	public Response changeBarcodeStatus(int pbId, int status, String user) {
		Response response = new Response();
		
		ProductBarcode pBarcode = productBarcodeDaoImpl.get(pbId, true);
		if (pBarcode == null) {
			response.setFail("无法找到条码信息,修改失败 : " + pbId );
		} else {
			pBarcode.setStatus(status);
			pBarcode.setLastUpdateBy(user);
			pBarcode.setLastUpdateTime(Common_util.getToday());
			productBarcodeDaoImpl.update(pBarcode, true);
			response.setSuccess("修改状态成功");
		}
		return response;
	}

}
